浏览器的预解析可以减缓渲染被阻塞的情况,例如文档解析过程中预加载器发现了 <script src="last.js"></script>
标签,会对 last.js 文件进行加载并放在浏览器缓存中,这样当解析器遇到这个 <script> 标记时,由于预加载器已经将 last.js 文件加载下来了,所以 last.js 会被立即执行,不需要等待从网络抓取资源,减缓了对渲染的阻塞。
二、CSS 和 JS 的处理顺序和阻塞分析
HTML 文档的解析和渲染过程中,外部样式表和脚本 顺序执行、并发加载。
JS 脚本会阻塞 HTML 文档的解析,包括 DOM 树的构建和渲染树的构建;CSS 样式表会阻塞渲染树的构建,但 DOM 树依然继续构建(除非遇到 script 标签且 css 文件此时仍未加载完成),但不会渲染绘制到页面上。
在 HTML 文档的解析过程中,解析器遇到 <script> 标记时会立即解析并执行脚本,HTML 文档的解析将被阻塞,直到脚本执行完毕。如果脚本是外部的,那么解析过程会停止,直到从网络抓取资源并解析和执行完成后,再继续解析后续内容。
理论上来说,应用样式表不会更改 DOM 树,因此似乎没有必要等待样式表并停止文档解析。但这涉及到一个问题,就是脚本在文档解析阶段会请求样式信息。如果当时还没有加载和解析样式,脚本就会获得错误的回复,这样显然会产生很多问题。这看上去是一个非典型案例,但事实上非常普遍。Firefox 在样式表加载和解析的过程中,会禁止所有脚本。而对于 WebKit 而言,仅当脚本尝试访问的样式属性可能受尚未加载的样式表影响时,它才会禁止该脚本。
但无论是哪种情况导致的阻塞,该加载的外部资源还是会加载,例如外部脚本、样式表和图片。HTML 文档的解析可能会被阻塞,但外部资源的加载不会被阻塞。
CSS 外部样式表的加载会阻塞外部脚本的执行,但并不会阻塞外部脚本的加载。这一点可以通过 chrome 调试工具中的 Network - Waterfall 进行验证,但是需要注意 chrome 的并发连接数(同一域名)上限为 6 个。
由上面两张截图可以看到,jquery.min.js 脚本文件与 bootstrap.css 等样式文件并行加载,但是由于 chrome 的并发连接数上限为 6 个,因此 bootstrap.min.js 脚本、xxx.css 样式等文件的加载会等待前面的文件加载完成,有可用连接数的时候才开始加载。
了解以上信息之后,我们可以对该页面进行相应优化,例如对CSS文件进行压缩处理、使用 CDN,将资源分布在多个域名下、合并 CSS 文件,减少 HTTP 请求数量等,来提高 CSS 的加载速度,减少 HTML 文档解析和渲染的阻塞时间。
browser only allows six TCP connections per origin on HTTP 1.
浏览器的并发请求数目限制是针对同一域名的。因此可以使用 CDN 加速技术来提高用户访问网站的响应速度,这样使用了 CDN 的资源加载不会占用当前域名下的并发连接数,从而减少阻塞的时间。
网页性能
了解 HTML 文档的解析和渲染的过程对于分析网页性能有着重要意义,它可以帮助我们找到影响网页性能的关键因素。例如,我们知道 JS 外部脚本的执行会阻塞文档的解析,那么重量级的第三方插件则会影响首页加载的速度,如果因此影响到了用户体验,我们就需要考虑这个第三方插件的使用成本是不是太高了,能否使用其他轻量级的插件进行替代,或者只使用其中一部分模块。
以 Datatables 为例:
上图是一个项目页面的 Network 截图,红色框中的部分出现了约 700ms 左右的空白,我们需要知道为什么页面的加载会出现这样的情况,这段空白时间浏览器在干什么?
我们分析 Timeline 图,看看浏览器在这段时间的具体信息,如下:
通过 Timeline 图我们可以看到,在 250ms~900ms 时间区间内,浏览器在执行 datatables.min.js 脚本代码,这个脚本的执行阻塞了文档的解析,耗时约 700ms,对应了 Network 图中的空白。
我们继续查看页面总的耗时时间,评估 700ms 耗时的影响,如下:
可以看到,页面总的完成耗时为 1.66s,由此可知 datatables.min.js 的执行耗时占了很大比重,应当慎重考虑是否一定要使用这个插件,能否使用其他轻量级的插件进行替代,或者能否精简插件的不必要模块,或者舍弃插件的使用。
参考资料-1
浏览器接收到html代码,可能是一份完整的文档,也可能是一个chunk,即开始解析。解析过程是先构建dom树,再根据dom树构建渲染树,最后浏览器将渲染树绘制到页面上。
构建dom树的过程即根据html代码自上而下进行构建,当遇到script文件加载/执行会阻塞后面dom树的构建(javascript可能会改变dom树),而遇到css文件则会阻塞渲染树的构建,即dom树依然继续构建(除非遇到script标签并且css文件依旧未加载完成),但不会渲染绘制到页面上。而无论哪个阻塞,该加载的文件还是会加载,例如html文档中的其他css/js/图片文件。
另外javascript被加载后就会被执行,执行的过程也阻塞树的构建。是执行完了才解析其他内容,而不是执行完了才加载其他内容。
作者:加冰
链接:https://www.zhihu.com/questio...
参考资料-2
首先,开源浏览器一般以8k每块下载html页面。
然后解析页面生成DOM树,遇到css标签或JS脚本标签就新起线程去下载他们,并继续构建DOM。
下载完后解析CSS为CSS规则树,浏览器结合CSS规则树和DOM树生成Render Tree。
注意:构建CSS Object Model(CSSOM)会阻塞JavaScript的执行。JavaScript的执行也会阻塞DOM的构建。
JavaScript下载后可以通过DOM API修改DOM,通过CSSOM API修改样式作用域Render Tree。
每次修改会造成Render Tree的重新布局和重绘。只要修改DOM或修改了元素的形状或大小,就会触发Reflow,单纯修改元素的颜色只需Repaint一下(调用操作系统Native GUI的API绘制)。
作者:陈金
链接:https://www.zhihu.com/questio...
本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!
以上就是浏览器解析渲染HTML文档的过程详解(图文)的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
通过14张有趣生动的图片来了解 flexbox 的用法(值得收藏)
html li标签是干嘛的?html li标签用法和属性的介绍
通过示例来了解css background强大的用法(值得收藏)
更多相关阅读请进入《javascript》频道 >>

Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者