一起了解script标签中的async和defer属性
前端当然要从 HTML 开始,我们来聊聊在 script 标签中加上 async/defer 时的功能及差异。
都明白的道理
我们都知道,浏览器解析 HTML 是一行一行按照顺序向后读取的,在传统的写法中,当浏览器读到 时,便会暂停解析 DOM,同时立即开始下载
中定义的资源,并在下载完成后立刻执行。由于这样的特性,可能会造成 DOM 树在还没有完全解析时就开始执行 JavaScript,需要操作 DOM 的程序可能因此无法正确执行,从而造成许多问题;或是由于
中的资源下载、执行时间过程,用户会卡在白画面,并会产生觉得网站太慢不好用之类的体验。
而解决方法也很简单,我们需要把 标签的位置都放到
的最后一行来避免 DOM 树解析不完全的问题,但是在复杂的网站中, HTML、JavaScript 的个头都很大,需要等到整个 DOM 树都载入完成才开始下载
内的资源,从网站读取完成到可操作,会产生明显的延迟感。
那这种问题该怎么解决呢?
从HTML4 开始, 多了
defer
属性,而 HTML5 则多了 async
,两者都是用来帮助开发者控制 内资源的载入及执行顺序,以及避免 DOM 的解析被资源下载卡住的。
defer
defer
的意思是延迟(Deferred),在 HTML4.01 规范 中规定:
设置后,这个布尔属性会向用户代理提示该脚本将不会生成任何网页内容(例如,JavaScript中不会生成 “document.write”),因此,用户代理可以继续解析和渲染。
也就是说,在加上 defer
属性后,浏览器会继续解析、渲染画面,而不会因为需要载入 内的资源而卡住;实际执行时,会在
DOMContentLoaded
执行之前,由上到下的依照摆放顺序触发。
听起来很方便对吧?但要提醒各位,虽然 W3C 规范上说 defer
属性会是一个布尔值,但 IE9 以前的版本是自定义的,即使写成