網頁開發中,網頁載入速度與用戶體驗息息相關。 為了提升網頁的效能,HTML 在 <script> 標籤中提供了兩個重要的屬性,async 和 defer,幫助開發者控制 JavaScript 的載入和執行方式。
一、預設情況下的 JavaScript 載入行為
在沒有 async 或 defer 屬性時,瀏覽器會依照 HTML 檔案的順序從上到下解析 DOM。 當遇到 <script> 標籤時,瀏覽器會暫停 DOM 的解析,開始下載並執行 JavaScript。 這種行為可能會導致網頁載入時間變長,因為瀏覽器必須等待腳本下載並執行完成後,才能繼續解析剩餘的 DOM。
二、添加 async 屬性
使用 async 屬性的 <script> 標籤會告訴瀏覽器在下載腳本時不必阻塞 HTML 解析。 換句話說,瀏覽器可以繼續解析 DOM,並同時在後台下載腳本。 一旦腳本下載完成,瀏覽器會立即中斷 DOM 的解析,並立即執行該腳本。
-
適用場景:加載網頁分析工具或是廣告腳本等,這些不需要等待 DOM 完全解析後才執行,不影響網頁內容的顯示。
由於腳本執行時機不定,如果該腳本依賴其他腳本,會導致錯誤產生。
<script src="script.js" async></script>
二、添加 defer 屬性
defer 屬性同樣允許下載腳本的同時繼續解析 HTML ,但不同的是帶有 defer 屬性的腳本會在 DOM 解析完成後才執行。
- 適用場景:適合用於需要 DOM 完全解析完的腳本,多個 defer 標籤的腳本會依序執行,可以保證腳本的依賴關係。
<script src="script.js" defer></script>
三、預設、async、defer 差異
-
預設情況
- 加載時機:依照 HTML 文件的順序從上到下解析 DOM,當解析到 <script> 標籤時加載
- 執行時機:腳本下載完成立即執行
- 使用場景:不依賴 DOM 且要求執行順序的腳本
-
async
- 加載時機:與 HTML 解析同時進行
- 執行時機:腳本下載完成立即執行
- 使用場景:不依賴 DOM 或其他腳本的獨立腳本
-
defer
- 加載時機:與 HTML 解析同時進行
- 執行時機:DOM 解析完後執行,且按順序執行
- 使用場景:依賴 DOM 或要求執行順序的腳本
四、結語
善用 async 和 defer 屬性有助於提升網頁的加載數度和用戶體驗。 開發者應根據腳本用途和依賴關係,選擇適當的屬性來確保網頁的高效加載和正確執行。