blog
blog copied to clipboard
彻底搞懂 async & defer
彻底搞懂 async & defer
TL;DR
两者都会并行下载,不会影响页面的解析。
defer 会按照顺序在 DOMContentLoaded 前按照页面出现顺序依次执行。
async 则是下载完立即执行。
兼容性
普通 script
先来看一个普通的 script 标签。
<script src="a.js"></script>
浏览器会做如下处理
- 停止解析 document.
- 请求 a.js
- 执行 a.js 中的脚本
- 继续解析 document
defer
<script src="d.js" defer></script>
<script src="e.js" defer></script>
- 不阻止解析 document, 并行下载 d.js, e.js
- 即使下载完 d.js, e.js 仍继续解析 document
- 按照页面中出现的顺序,在其他同步脚本执行后,
DOMContentLoaded
事件前 依次执行 d.js, e.js。
async
<script src="b.js" async></script>
<script src="c.js" async></script>
- 不阻止解析 document, 并行下载 b.js, c.js
- 当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在
DOMContentLoaded
事件前或者后 )
其他
- 如果 script 无 src 属性,则 defer, async 会被忽略
- 动态添加的 script 标签隐含 async 属性。
结论
- 两者都不会阻止 document 的解析
- defer 会在 DOMContentLoaded 前依次执行 (可以利用这两点哦!)
- async 则是下载完立即执行,不一定是在 DOMContentLoaded 前
- async 因为顺序无关,所以很适合像 Google Analytics 这样的无依赖脚本
Reference
- http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
- http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/
- http://javascript.tutorialhorizon.com/2015/08/11/script-async-defer-attribute/
- http://stackoverflow.com/questions/10808109/script-tag-async-defer
- https://segmentfault.com/q/1010000000640869
两者都不会阻止 document 的解析 defer 会在 DOMContentLoaded 前依次执行 (可以利用这两点哦!) async 则是下载完立即执行,不一定是在 DOMContentLoaded 前 async 因为顺序无关,所以很适合像 Google Analytics 这样的无依赖脚本
那是否认为 defer 可以替代普通的 script 标签?
@quanru 不可以啊 因为有可能 js 会修改 dom 啊
@xiaoyu2er 受教了~
@quanru 不可以啊 因为有可能 js 会修改 dom 啊
普通script标签内有js,带defer的script标签内也有js,都有可能修改DOM。在修改dom这点上,怎么论证“defer不能替代普通的script标签”呢?
赞 多谢分享
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
<script defer src="myscript.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
async会阻止DOM parase
Defer 会阻止DOM parase
你这图是async运行时会HTML parsing paused,defer不会
Defer 会阻止DOM parase
你这图是async运行时会HTML parsing paused,defer不会
他本来说的就是async会阻塞HTML解析,可作者说的是两者都不会阻塞HTML解析,明显是错误的。
Defer 会阻止DOM parase
你这图是async运行时会HTML parsing paused,defer不会
他本来说的就是async会阻塞HTML解析,可作者说的是两者都不会阻塞HTML解析,明显是错误的。
下载的时候不阻塞,执行的时候阻塞。