說明
![[譯] async 與 defer](https://i.iter01.com/images/9c5c17a1ad14d6d8905732e552a0f38fdeb1f04fa22f21f24361d5c574584273.png)
<script>
讓我們從定義沒有任何屬性的<script>
開始。HTML 檔案會被解析直到命中指令碼檔案,那個時候,HTML 將會停止解析並且將會傳送一個請求去獲取這個檔案(如果他是外鏈),在 HTML 繼續解析之前,指令碼將會被執行。
![[譯] async 與 defer](https://i.iter01.com/images/ce52609dd2af85f84f345b301b980df4fd50d1f10479f71bd7bccd07aa0c5377.png)
<script async>
async
在 HTML 解析的同時下載檔案,而且當檔案完成下載之後,將會暫停 HTML 解析來執行檔案。
![[譯] async 與 defer](https://i.iter01.com/images/d435941b11c6ff559b6558f48fa1df32016cdbc2b642959a3b32c6a76a2373a4.png)
<script defer>
defer
在 HTML 解析的同時下載檔案, 並且在 HTML 解析完成後才執行它,defer
的多指令碼也保證了他們以它們出現在文件上的順序被順序執行。
![[譯] async 與 defer](https://i.iter01.com/images/90b37006278f8444721acfcf39518a7e3dcd1888138684e03398492300145e65.png)
我什麼時候應該用什麼?
通常,您希望儘可能使用 async
, 然後是 defer
, 再是沒有這些屬性的指令碼。這裡有一些常用的規則去遵守。
- 如果指令碼是模組,並且沒有依賴其他任何指令碼時用
async
- 如果指令碼依賴或者被其他指令碼依賴時用
defer
- 如果指令碼檔案很小,並且被一個
async
指令碼依賴時用沒有非同步屬性的內聯指令碼,並且放在 async 指令碼上方。
支援
IE9 及以下在實現 defer 的時候有一些特別嚴重的 bug,以至於指令碼的執行順序無法被保證,如果你需要支援 IE9 及以下,建議不要全部用 defer,並且對你的指令碼不新增任何屬性,如果執行順序很重要。閱讀屬性說明檔案
譯者總結
- defer 和 async 下載都是非同步的
- defer 在 檔案解析完成時(DOMContentLoaded之前)執行,async 在下載完成後執行
- 多個 defer 的執行順序和他們出現在頁面上的順序一致
- async 的執行順序無法保證。