- 这里略去从输入URL到页面开始加载的细节,从获取到页面文件,也就是页面对应的HTML文件开始。该文档会自上而下的被解析。渲染引擎的HTML解析器负责把HTML字节流转换成DOM。DOM是浏览器环境提供的JavaScript和Web页面内容交互的接口。
- 页面的解析和渲染,和HTML、CSS、JavaScript之前的相互关系是有关联的——或者说,正因为有关联,所以页面的解析和渲染必须遵循一定的解析顺序/规则。
- HTML产生DOM后(也就是document对象),会结合CSSOM(也就是stylesheet对象),生成布局树。CSS不会阻塞DOM的解析,DOM和CSSOM会并行去解析。一旦生成布局树,浏览器就会开始处理图层、绘制、光栅化、合成和显示页面了。
- DOMContentLoaded事件对应DOM解析完成;而Load事件对应的是页面完全加载完毕(包括各种图片、视频、音频等资源的下载)
- JavaScript可以和Web页面上的一切内容交互,这就导致JavaScript成为造成阻塞的大头。
- 当HTML解析器遇到
<script>
标签的时候,会暂停DOM的解析,转而去下载并执行JavaScript脚本,JavaScript脚本执行完才继续往下解析。 - 可以给
<script>
增加async
或者defer
属性。他们等于显式地指明这个脚本不会影响DOM的渲染,从而允许其下载和DOM解析并行。具体增加什么属性,要根据这段JavaScript脚本有什么作用决定。- async的脚本:会在下载后立刻执行,如果有多个这样的脚本,执行顺序将不可控,这一点必须注意。如果在DOM解析完成前下载完,其执行依然会阻塞DOM解析。
- defer的脚本:会在DOMContentLoaded事件之后执行,因此将不会阻塞DOM的解析。
- 所以尽可能的把CSS文件放在文档的头部(
<head>
标签里),而把JavaScript文件放在文档的尾部(<body>
标签里的最后),能有助于页面尽快的渲染出来。
- 当HTML解析器遇到
- 现在的浏览器都做了一个优化,会在开始解析HTML之前发现并提前下载CSS和JavaScript文件,而不是等挨个解析到了那些标签后才开始下载、执行。同域名最多可以有6个TCP链接,使得这些文件可以并行下载。这个优化使得多个文件的下载时间产生重叠,从而减少了阻塞时间。在开发者工具里,我们会看到,获取到页面文件后,会同时开启各种CSS、JavaScript文件的并行下载。
- 页面白屏问题:
- CSSOM有两个作用:给布局树提供基础样式信息;给JavaScript操作样式表的能力/Api(就是document.stylesheet这货)
- DOM解析完成后,页面是不会显示的。因为DOM要和CSSOM一起生成布局树。CSS解析慢了就会阻塞布局树的生成,推迟页面的显示。
- 如果页面上还有JavaScript脚本,CSS还可能会阻塞JavaScript的执行从而间接阻塞DOM的解析——因为JavaScript有操作样式表的可能。前面提到浏览器做了优化,CSS文件和JS文件会并行下载,但是不管谁先下载完,JavaScript脚本都得等到CSSOM生成后才开始执行。