WebKit的HTML解析顺序和优化

JavaScript和DOM文档解析的顺序

总体上看,整个Web页面数据的解析处理模型是一个同步的过程,当在解析HTML文档时,一旦出现了<script>标签,Web开发者期望JavaScript程序能够立即得到解析和执行,而HTML文档的解析流程就会被暂停,直到JavaScript脚本解析执行完毕后,才重新恢复原来的解析流程。当JavaScript脚本可以存放在HTML外部,并非采用嵌入式的脚本时,那么WebKit就必须先发起JavaScript脚本资源请求,从网络上下载该脚本,然后再解析执行,这一系列过程依然是同步的,等JavaScript执行完毕后,才重新恢复原来的HTML文档解析流程。这个处理模型已经使用了许多年,也已经定义成了标准,记录在W3C定义的HTML4和HTML5的文档规范中。

所以为了网页能快速的展现给用户,当JavaScript脚本不会改变文档内容或结构时,Web开发者一般把外部的JavaScript脚本文件写在HTML页面的最后,这样就可以避免因为加载和执行外部脚本消耗太多时间,影响页面的渲染速度。

实例代码如下:

<html>
<body>
<script type="text/javascript">
console.log(document.getElementById("p1"));
window.onload = function() {
console.log(document.getElementById("p1"));
}
</script>
<p id="p1">Hello World!</p>
<script type="text/javascript">
console.log(document.getElementById("p1"));
</script>
</body>
</html>

第一次调用函数document.getElementById("p1")时返回null,这是因为HTML文档还没有解析完毕,先去解析和执行JavaScript脚本;当文档加载完成后触发onload消息,在onload的消息处理函数中调用该函数时返回<p id="p1">Hello World!</p>。在文档最后调用该函数时同样返回<p id="p1">Hello World!</p>,因为DOM文档的解析是顺序执行的,当最后一次遇到<javascript>时DOM树已经构建完成。

HTML5给JavaScript脚本定义了一个新的属性”defer”,该属性规定是否对脚本执行进行延迟,直到页面加载完毕后才开始加载和执行。该属性与上述方案的作用相同,只是目前只有IE支持它,Chrome浏览器不支持。

HTML文档预解析(Speculative Parsing)

从上节中,可以得知HTML解析只能发生在主线程中,并且会被<javascript>阻塞,直到JavaScript脚本从网络上加载并且解析执行完毕之后,才能恢复HTML的解析过程。这个阻塞过程很大程度上影响网页显示的性能,所以WebKit和FireFox对上述过程做了优化,当HTML解析的过程中遇到<javascript>时,主线程依然去下载和解析执行JavaScript脚本,另外HTML解析流程此时不会一直等待JavaScript的执行完毕,而是在另外一个线程中进行HTML预解析流程,比如去加载其他的JavaScript脚本,图片,音视频资源文件等等。既然是预测性的加载,当然就有可能成功,也有可能失败。当JavaScript脚本中显示调用了”document.write()”或”document.createElement(“”)”等改变DOM结构的语句时,就可能导致先前预测的执行无效,当推测失败时,上述推测性的HTML解析工作将宣告无效,需要在主线程中重新同步执行,这就回到了最原始的加载流程。但是如果推测成功,那主线程可直接采用子线程运行的结果,没有必要重新加载、解析和执行,这就做到了多个JavaScript、CSS、Image资源文件的并行处理,从而在整体上提高了HTML文档解析的效率。

CSS解析

直观上看,CSS只是对DOM节点进行装饰,例如设置DOM节点的背景色,DOM节点的宽度,左右上下间隙等,这只会在DOM树的渲染和布局时才会用到,并且不会改变DOM树的结构,那么似乎可以想象,在解析HTML文档的过程中遇到CSS资源文件时,是不是不用等待CSS资源文件的加载和解析完成,就可以并行的继续解析HTML文档呢?但是这里有个问题就是JavaScript脚本有时需要访问CSS中的信息,如果CSS文件没有加载和解析完成的话,那么JavaScript脚本访问的数据将会是不正确的,这直接导致错误的网页排版和布局,这是用户不能接受的。上述情况看起来貌似属于特例,但实际上开发者经常会这样使用。所以针对上述情况,Firefox采取一刀切的措施,暂停所有的JavaScript解析直到CSS资源文件加载和解析完毕,而WebKit处理方式似乎更加灵活,它只会暂定那些试图访问某些没有被加载完成的CSS属性的JavaScript。

参考文档

1.     http://taligarsiel.com/Projects/howbrowserswork1.htm#The_order_of_processing_scripts_and_style_sheets

2.     https://developer.mozilla.org/en-US/docs/HTML/Optimizing_Your_Pages_for_Speculative_Parsing

3.     http://www.w3school.com.cn/tags/att_script_defer.asp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值