新手指南:JavaScript 中的 defer 和 async 屬性
更新日期: 2024 年 10 月 25 日
在網頁開發中,我們經常需要在 HTML 中引入 JavaScript 腳本,以增強網頁的功能。
然而,JavaScript 腳本的加載和執行方式,可能會影響網頁的性能和用戶體驗。
為了解決這些問題,我們可以使用 defer
和 async
來控制 JavaScript 的加載時機。
這篇文章將介紹這兩個屬性之間的區別,以及它們在實際應用中的最佳用法。
JavaScript 腳本加載的基礎知識
當我們在 HTML 中引入 JavaScript 腳本時,最常見的做法是使用 <script>
標籤:
<script src="script.js"></script>
默認情況下,瀏覽器會順序地下載和執行這些腳本。
在 HTML 解析器解析頁面時,如果遇到 <script>
標籤,解析器會暫停 HTML 解析,等待 JavaScript 腳本加載並執行完成後,才繼續解析剩下的 HTML。
這種行為可能會導致頁面加載變慢,尤其是在腳本很大或需要較多時間加載的情況下。
為了更好地優化網頁的加載性能,我們可以使用 defer
或 async
屬性來控制腳本的加載和執行方式。
defer
和 async
屬性的介紹
defer
和 async
是兩個可以加到 <script>
標籤中的屬性,它們的目的是讓 JavaScript 腳本更靈活地與 HTML 一起加載。
defer
屬性
defer
屬性告訴瀏覽器異步下載腳本,但腳本的執行會在整個 HTML 文檔解析完成後才進行。
這意味著帶有 defer
的腳本會等到 DOM 樹構建完成後才執行,並且按照它們在文檔中的出現順序執行。
範例:
<script src="script.js" defer></script>
特點:
- 腳本異步加載,不會阻塞 HTML 解析。
- 腳本在文檔解析完成後才執行。
- 如果有多個
defer
腳本,它們會按順序執行。
async
屬性
async
屬性同樣會讓腳本異步下載,但與 defer
不同的是,一旦腳本下載完成,它就會立刻執行,無論 HTML 是否解析完成。
因此,async
腳本的執行時間不確定,取決於腳本的下載速度和其他腳本的執行狀況。
範例:
<script src="script.js" async></script>
特點:
- 腳本異步加載,不會阻塞 HTML 解析。
- 一旦腳本加載完成,它會立即執行。
- 多個
async
腳本的執行順序不保證,可能會根據它們的下載速度而有所不同。
defer
和 async
的區別
總結來說,defer
和 async
的主要區別在於它們的執行時機:
屬性 | 加載方式 | 執行時機 | 執行順序 |
---|---|---|---|
defer | 異步加載 | 文檔解析完成後執行 | 按照腳本在 HTML 中的順序 |
async | 異步加載 | 腳本加載完成後立即執行 | 無法保證順序 |
何時使用 defer
?
- 當你的腳本依賴於完整的 DOM(例如操作 DOM 元素)時,
defer
是理想的選擇,因為它保證了腳本在整個文檔解析完成後才執行。 - 當你有多個腳本,並且希望它們按順序執行時,也應該使用
defer
。
何時使用 async
?
- 當你的腳本不依賴於其他腳本或 DOM 結構時,可以使用
async
。
例如,分析代碼或廣告腳本通常會用async
,因為它們不影響主頁面的其他部分,而且可以快速加載並執行。
使用場景範例
讓我們來看一些實際的使用場景,以幫助理解何時選擇 defer
或 async
。
使用 defer
的範例
假設你有一個 JavaScript 腳本需要操作網頁中的元素,例如添加點擊事件或修改 HTML 內容。這些操作需要在 DOM 構建完成後進行,因此使用 defer
來確保腳本的執行時機是適當的。
<script src="dom-manipulation.js" defer></script>
在這裡,我們使用了 defer
,這樣可以確保 dom-manipulation.js
在文檔完全解析後執行,保證腳本不會因為找不到 DOM 元素而報錯。
使用 async
的範例
假設你有一個第三方的網站分析工具腳本,例如 Google Analytics。
這類腳本不依賴於頁面的其他部分,也不需要操作 DOM,並且你希望它盡可能快速地加載並執行,因此適合使用 async
。
<script src="https://www.google-analytics.com/analytics.js" async></script>
在這裡,我們使用 async
,這樣可以確保分析腳本不會影響頁面其他部分的加載速度,而且可以在下載完成後立即執行。
小結
在 HTML 中引入 JavaScript 時,理解 defer
和 async
的使用可以幫助我們優化網頁的性能和用戶體驗。
defer
:腳本異步加載,在文檔解析完成後按順序執行,適用於需要完整 DOM 結構的腳本。async
:腳本異步加載,一旦加載完成就立即執行,適用於不依賴其他腳本和 DOM 的獨立腳本。
選擇合適的屬性可以讓你的網頁加載更快速、更高效,並且減少阻塞現象,提高整體的用戶體驗。
希望這篇文章能幫助你理解 defer
和 async
的概念,並且在你下次開發網頁時靈活運用這些屬性!