HTML5 <script>元素async,defer异步加载

原文地址:HTML5′s async Script Attribute
(译者注: 异步加载,可以理解为无阻塞并发处理.)

(译者再注: 建议使用 defer,但是经测试发现 defer 属性对页面内的script无效,没有时序差别.只对外部 js文件生效 )

我对于HTML5感到兴奋不已的原因之一是它实现了众多业界期待已久的特性。我们一直需要输入框显示空白提示,但都是用JavaScript来实现的。我们也想要整个块都变成可被点击,也是使用javascript来实现。
现在WebKit为html5实现了SCRIPT标签的async异步属性。过去我们使用各种JavaScript技巧来做这种事情,但现在新的属性让防止阻塞变得相对容易。

async - HTML属性

如我前面提到的,添加async属性非常简单:

<!-- 指定async,以及 onload 回调-->  
<script async src="siteScript.js" onload="myInit()"></script>  

事实上,如果你的JavaScript以及HTML结构设计的合理,那么90%的情况下你的Script元素可以使用异步加载。

defer - HTML属性

Safari 浏览器额外添加了defer属性

<!-- 指定defer,效果和async差不多-->  
<script defer src="siteScript.js" onload="myInit()"></script>  

async 与 defer 的差别

正常情况下,当浏览器在解析HTML源文件时如果遇到外部的script,那么解析过程会暂停,并发送请求来下载script文件,只有script完全下载并执行后才会继续执行DOM解析。比如:

在下载过程中浏览器是被阻止做其他有用的工作的,包括 解析HTML,执行其他脚本,以及展示CSS布局。虽然Webkit预加载扫描程序可以探测性地在下载阶段进行多线程下载,但是某些页面仍然存在很大的网络延迟。
当前有很多技术来提升页面显示速度,但都需要额外的代码以及针对特定浏览器的技巧。现在,script可以通过添加async或者defer属性来让脚本不必同步执行,示例如下:

<script async src="myAsyncScript.js" onload="myInit()"></script>  
<script defer src="myDeferScript.js" onload="myInit()"></script

两者的区别在于执行时的不同:
async 脚本在script文件下载完成后会立即执行,并且其执行时间一定在 window的load事件触发之前。这意味着多个async脚本很可能不会按其在页面中的出现次序顺序执行。
与此相对,浏览器确保多个 defer 脚本按其在HTML页面中的出现顺序依次执行,且执行时机为DOM解析完成后,document的DOMContentLoaded 事件触发之前。

posted @ 2017-08-15 11:04  joe_ice  阅读(183)  评论(0)    收藏  举报