Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

SCRIPT的defer属性实现差异

  defer这个属性最初是IE的,在DOMContentLoaded事件被支持以前它确实很有效。其实它的功能就是把脚本延迟到文档加载并解析完毕后执行。这个功能很简单,但其定义还是不够不严谨。最新的规范中有一些相关的解释,只是目前的浏览器的实现依然存在差异。
  如果SCRIPT标签需要请求js文件,这个请求是在解析标签时发起的异步请求。请求并不延后,只是执行延后了而已,对于这部分的实现都是一致的。之后浏览器对带有defer属性的SCRIPT的概念理解可能就有分歧了。一种理解方式是将其作为文档本身的一部分、另一种是作为文档的额外资源。前者类似普通的SCRIPT标记,它的加载与执行是会影响到文档本身的加载完成的。而后者则是类似图片加载的概念,文档加载完成不需要它的参与。也就是说,前者会因为带defer的SCRIPT标记请求的资源没加载完成而延后DOMContentLoaded的触发。后者则不延后DOMContentLoaded,但是也总是在load事件之前完成。比如下面这个测试:
//defer.php
header('Content-Type: text/javascript');
sleep(5);
echo 'console.log("defer");';
<script defer src="defer.php"></script>
<script>
document.addEventListener("DOMContentLoaded",function(e){
  console.log("DOMReady");
});
addEventListener("load",function(e){
  console.log("load");
});
setInterval(function(){
  console.log("running");
},1000);
</script>

  Chrome和IE的行为是相同的,他们将defer的SCRIPT标记作为文档的一部分,延后了DOMContentLoaded的触发,而Firefox则将其作为一个额外资源,在load事件前触发(如果js加载速度很快,而文档加载速度很慢的话,也可能在DOMContentLoaded之前触发)。

  测试于:
    Chrome 32
    Firefox 26
    IE 11
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^