高效加載JavaScript:使用defer和async

在HTML頁面中加載腳本時,你需要小心,以避免影響頁面的加載性能。根據你在HTML頁面中添加腳本的位置和方式,將影響加載時間。 位置的重要性 async和defer 性能比較 沒有defer或async,在head中 沒有defer或async,在body中 使用async,在head中 使用defer,在head中 阻塞解析 阻塞渲染 domInteractive 保持順序 告訴我最好的方法 在HTML頁面中加載腳本時,你需要小心,以避免影響頁面的加載性能。 傳統上,腳本是以以下方式包含在頁面中: <script src="script.js"></script> 當HTML解析器找到這行代碼時,將發出請求以獲取腳本並執行它。 一旦此過程完成,解析可以繼續,並分析頁面的其餘內容。 正如你可以想像的,此操作對頁面的加載時間產生了巨大影響。 如果腳本加載時間比預期的要長,例如如果網絡速度較慢,或者如果你使用的是移動設備且連接不穩定,訪問者可能會看到一個空白頁面,直到腳本加載並執行完成。 位置的重要性 當你初學HTML時,你被告知腳本標籤位於<head>標籤中: <html> <head> <title>標題</title> <script src="script.js"></script> </head> <body> ... </body> </html> 正如之前所說,當解析器找到這行代碼時,它將獲取腳本並執行它。 然後,在完成這個任務之後,它繼續解析body。 這樣做是不好的,因為會引入很多延遲。解決這個問題的一個常見解決方案是將script標籤放在頁面底部,即在結束的</body>標籤之前。 這樣做可以在頁面已經解析和加載完成之後加載和執行腳本,這對於不支持HTML的兩個相對新的功能(async和defer)的舊瀏覽器來說是一個巨大的改進。 如果你需要支持不支持async和defer的舊瀏覽器,這是你可以做的最好的事情。 async和defer async和defer都是布爾屬性。它們的使用方式類似: <script async src="script.js"></script> <script defer src="script.js"></script> 如果你同時指定了這兩個屬性,對於現代瀏覽器來說,async的優先級更高,而對於支持defer但不支持async的舊瀏覽器,則會回退到使用defer。 有關支持情況的詳細信息,可以參考 caniuse.com 中的 async https://caniuse.com/#feat=script-async 和 defer https://caniuse.com/#feat=script-defer 只有在將腳本放在頁面的head部分時,這些屬性才有意義,如果將腳本放在上面看到的body底部,則這些屬性將無效。 性能比較 沒有defer或async,在head中 以下是一個在head部分中未使用defer或async的腳本加載方式: 解析過程在獲取腳本並執行之前暫停,腳本執行完成後解析繼續。 沒有defer或async,在body中 以下是一個在body標籤結束之前並未使用defer或async的腳本加載方式: 解析過程不會暫停,並且腳本在解析完成之後被獲取並執行。解析在腳本甚至下載之前完成,因此頁面在之前的示例中更早地顯示給用戶。 使用async,在head中 以下是一個在head標籤中使用async的腳本加載方式: 腳本異步獲取,當腳本準備好時,HTML解析將暫停以執行腳本,然後繼續解析。 使用defer,在head中 以下是一個在head標籤中使用defer的腳本加載方式: 腳本異步獲取,並且僅在HTML解析完成後才執行。 解析完成的方式與將腳本放在body標籤結束時相同,但是腳本執行的時間總體上更早,因為腳本已經在HTML解析期間並行下載。...