Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOMContentLoaded解析 #209

Open
louzhedong opened this issue Mar 26, 2020 · 0 comments
Open

DOMContentLoaded解析 #209

louzhedong opened this issue Mar 26, 2020 · 0 comments

Comments

@louzhedong
Copy link
Owner

DOMContentLoaded

当一个 HTML 文档被加载和解析完成后,DOMContentLoaded 事件便会被触发。

浏览器渲染原理

浏览器向服务器请求到了HTML文档后便开始解析,生成DOM(文档对象模型),此时HTML就被加载和解析完成了。如果有CSS会根据CSS生成CSSOM(CSS对象模型),然后再由DOM和CSSOM合成并产生渲染树。有了渲染树,知道了所有节点的样式,下面便根据这些节点以及样式计算它们在浏览器中确切的大小和位置,这就是布局阶段。有了以上这些信息,下面就把节点绘制到浏览器上。如下图:

当页面中有JavaScript时,情况又会不一样

同步脚本

JavaScript可以阻塞DOM的生成,当浏览器再解析HTML时,如果遇到<script>,便会停下对HTML的解析,转而去处理脚本。如果是内联的,会先处理脚本,如果是外链的,会先加载脚本,然后执行。

另外,因为JavaScript可以查询任意对象的样式,所以意味着在 CSS 解析完成,也就是 CSSOM 生成之后,JavaScript 才可以被执行。

到这里,我们可以总结一下。当文档中没有脚本时,浏览器解析完文档便能触发 DOMContentLoaded 事件;如果文档中包含脚本,则脚本会阻塞文档的解析,而脚本需要等 CSSOM 构建完成才能执行。在任何情况下,DOMContentLoaded 的触发不需要等待图片等其他资源加载完成。

异步脚本
  • defer

    当 HTML 文档被解析时如果遇见 defer 脚本,则在后台加载脚本,文档解析过程不中断,而等文档解析结束之后,defer 脚本执行。另外,defer 脚本的执行顺序与定义时的位置有关。在前面的script会先执行

  • async

    当 HTML 文档被解析时如果遇见 async 脚本,则在后台加载脚本,文档解析过程不中断。脚本加载完成后,文档停止解析,脚本执行,执行结束后文档继续解析

defer与DOMContentLoaded

如果 script 标签中包含 defer,那么这一块脚本将不会影响 HTML 文档的解析,而是等到 HTML 解析完成后才会执行。而 DOMContentLoaded 只有在 defer 脚本执行结束后才会被触发。 所以这意味着什么呢?HTML 文档解析不受影响,等 DOM 构建完成之后 defer 脚本执行,但脚本执行之前需要等待 CSSOM 构建完成。在 DOM、CSSOM 构建完毕,defer 脚本执行完成之后,DOMContentLoaded 事件触发。

async与DOMContentLoaded

如果 script 标签中包含 async,则 HTML 文档构建不受影响,解析完毕后,DOMContentLoaded 触发,而不需要等待 async 脚本执行、样式表加载等等。

DomContentLoaded 事件只关注 HTML 是否被解析完,而不关注 async 脚本

DOMContentLoaded和load

当 HTML 文档解析完成就会触发 DOMContentLoaded,而所有资源加载完成之后,load 事件才会被触发。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant