紀錄工作經驗、相關知識,解決技術相關問題。

HTML

JS script async vs defer 差異比較:非同步載入執行順序圖解

JS script async vs defer 差異比較:非同步載入執行順序圖解 特色圖片

在網頁開發中,瀏覽器解析 HTML 時若遇到 <script> 標籤,預設會暫停 DOM 解析並立即下載與執行該腳本,這往往是導致頁面渲染阻塞(白畫面)的主因。透過 async 與 defer 屬性,開發者可以改變腳本的載入與執行行為。

⚡ 快速跳轉(依實務情境選擇):
預設行為 | async 機制 | defer 機制 | 規格對照表

規格對照表

屬性下載時機執行時機是否阻塞 HTML 解析
預設暫停解析,立即下載下載完成後立即執行是(阻塞)
async非同步下載下載完成後立即執行執行時阻塞
defer非同步下載DOM 解析完成後依序執行否(不阻塞)

預設行為:同步載入

當 <script> 標籤不帶任何屬性時,瀏覽器會採取同步載入模式:

<script src="demo.js"></script>

行為機制:

  1. 遇到 <script> 時,暫停 DOM 解析。
  2. 開始下載腳本。
  3. 下載完成後,立即執行該腳本。
  4. 腳本執行完畢後,恢復 DOM 解析。

若腳本檔案過大或網路延遲,會導致頁面出現明顯的渲染停滯。

async 機制:非同步載入

async 屬性讓腳本在背景進行非同步下載,一旦下載完成,瀏覽器會暫停 DOM 解析並立即執行該腳本。

<script src="demo.js" async></script>

核心特性:

  • 不保證執行順序:若頁面有多個 async 腳本,誰先下載完就先執行誰,與在 HTML 中的排列順序無關。
  • 適用場景:適合用於獨立腳本,即不依賴其他腳本、也不被其他腳本依賴的程式碼,例如 Google Analytics 或廣告追蹤碼。

defer 機制:延遲載入

defer 屬性同樣在背景進行非同步下載,但它保證腳本會在 HTML 解析完成後、DOMContentLoaded 事件觸發前依序執行。

<script src="demo.js" defer></script>

核心特性:

  • 保證執行順序:即使腳本下載速度不同,瀏覽器也會嚴格按照它們在 HTML 中出現的順序執行。
  • 適用場景:適合用於依賴 DOM 的腳本,或是需要確保執行順序的模組化程式碼。這是現代網頁開發中最推薦的預設載入方式。

常見問題 Q&A

1. 如果同時設定 async 和 defer 會發生什麼事?

若瀏覽器同時支援這兩個屬性,async 的優先級較高。瀏覽器會忽略 defer,將其視為 async 處理。為了避免混淆,建議擇一使用即可。

2. 為什麼現代開發推薦預設使用 defer?

因為 defer 不會中斷 DOM 解析,且能確保腳本在頁面結構準備好後才執行,這能大幅提升首屏渲染效能(FCP),同時避免因腳本過早執行而找不到 DOM 元素的錯誤。

3. async 腳本會影響 DOMContentLoaded 嗎?

async 腳本的執行時機是不確定的,它可能會在 DOMContentLoaded 之前或之後執行。因此,如果你的程式碼需要確保 DOM 已經準備好,請務必使用 defer 或在程式碼中監聽 DOMContentLoaded 事件。

4. 如何選擇適合的載入方式?

  • 無依賴、第三方追蹤碼:使用 async。
  • 需要操作 DOM、有執行順序要求:使用 defer。
  • 極少數必須在 HTML 解析前執行的腳本:使用預設同步模式。

參考資料與延伸閱讀

6 留言

  1. After reading your article, it reminded me of some things about gate io that I studied before. The content is similar to yours, but your thinking is very special, which gave me a different idea. Thank you. But I still have some questions I want to ask you, I will always pay attention. Thanks.

  2. Your point of view caught my eye and was very interesting. Thanks. I have a question for you. https://www.binance.com/zh-CN/register?ref=V2H9AFPY

  3. I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article. https://www.binance.com/ru-UA/register?ref=V2H9AFPY

  4. Reading your article has greatly helped me, and I agree with you. But I still have some questions. Can you help me? I will pay attention to your answer. thank you.

  5. Reading your article helped me a lot and I agree with you. But I still have some doubts, can you clarify for me? I’ll keep an eye out for your answers.

  6. I have read your article carefully and I agree with you very much. This has provided a great help for my thesis writing, and I will seriously improve it. However, I don’t know much about a certain place. Can you help me?

發表迴響