原文地址:https://github.com/xiaoyu2er/blog/issues/8
普通 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