浏览器是如何解析html的?

当我们在浏览器地址栏输入一个合法的url时,浏览器首先进行DNS域名解析,拿到服务器IP地址后,浏览器给服务器发送GET请求,等到服务器正常返回后浏览器开始下载并解析html。这里仅总结浏览器解析html的过程。

html页面主要由domcssjavascript等部分构成,其中cssjavascript既能内联也能以脚本的形式引入,当然html中还可能引入imgiframe等其他资源。其实所有的这些资源也是以dom标签的形式嵌入在html页面中的,因此本篇总结说的html解析过程就是dom的解析过程。

1 dom解析过程

整个dom的解析过程是顺序,并且渐进式的。

顺序指的是从第一行开始,一行一行依次解析;渐进式则指得是浏览器会迫不及待的将解析完成的部分显示出来,如果我们做下面这个实验会发现,在断点处第一个div已经在浏览器渲染出来了:


<html>
<head>
head>
<body>
    <div>
        first div
    div>
    <script>
        debugger
    script>
    <div>
        second div
    div>
body>
html>
复制代码

既然dom是从第一行按顺序解析,那么我们怎么判断dom何时解析完成呢?这个问题应该经常会在面试中问到,比如一般会问:

window.onloadDOMContentLoaded有什么区别?

其实就是想看看是不是明白dom树何时构建完成,这个问题确实很重要,尤其是对于几年前的jquery技术栈来说,因为我们使用javascript操作dom或者给dom绑定事件有个前提条件就是需要dom树已经创建完成。整个html页面的dom解析完成时,dom树也就构建完成了。dom树构建完成后document对象会派发事件DOMContentLoaded来通知dom树已构建完成。

html从第一行开始解析,遇到外联资源(外联css外联javascriptimageiframe等)就会请求对应资源,那么请求过程是否会阻塞dom的解析过程呢?答案是看情况,有的资源会,有的资源不会。下面按是否会阻塞页面解析分为两类:阻塞型非阻塞型,注意这里区分两类资源的标志是document对象派发DOMContentLoaded事件的时间点,认为派发DOMContentLoaded事件才表示dom树构建完成。

1.1 阻塞型

会阻塞dom解析的资源主要包括:

  • 内联css
  • 内联javascript
  • 外联普通javascript
  • 外联defer javascript
  • javascript标签之前的外联css

外联javascript可以用asyncdefer标示,因此这里分为了三类:外联普通javascript外联defer javascript外联async javascript,这几类外联javascript本篇后面有详细介绍。 dom解析过程中遇到外联普通javascript会暂停解析,请求拿到javascript并执行,然后继续解析dom树

对于外联defer javascript这里重点说明下为什么也归于阻塞型。前面也说了,这里以document对象派发DOMContentLoaded事件来标识dom树构建完成,而defer javascript是在该事件派发之前请求并执行的,因此也归类于阻塞型,但是需要知道,deferjavascript实际上是在dom树构建完成与派发DOMContentLoaded事件之间请求并执行的,不过如果换个思路理解,

你可能感兴趣的:(浏览器是如何解析html的?)