解釋非同步與延遲 JavaScript
在大多數情況下,每當我們使用指令碼標籤載入任何 JavaScript 程式碼時,瀏覽器在遇到指令碼標籤時會暫停 HTML 處理,並首先開始下載 JavaScript 檔案。在瀏覽器完成指令碼下載和執行之前,HTML 元素指令碼標籤將不會被啟用。瀏覽器等待指令碼下載、執行,然後在處理頁面其餘部分之前進行處理。
在較新的瀏覽器中,指令碼的潛在大小可能大於 HTML 檔案,這會增加下載大小和處理時間。透過限制使用者瀏覽網站的能力,這會延長頁面的載入時間。為了解決此問題,使用了 async 和 defer 屬性。
語法
頁面包含一個標準指令碼,其方式如下所述。
<script src = "script.js"></script>
當 HTML 解析器遇到此元素時,它會向伺服器傳送請求以獲取指令碼。
非同步
每當使用 async 屬性時,指令碼將與頁面其餘部分非同步下載,既不會延遲頁面內容的處理和呈現,也不會延遲 HTML 解析。在指令碼下載後以及指令碼開始執行後,HTML 解析將停止。執行後,HTML 處理將繼續。頁面或任何其他指令碼都不期望非同步指令碼,反之亦然。對於位於外部的獨立指令碼,它非常有效。
當有很多迭代或迴圈內的活動很複雜時,需要非同步迴圈。但是,對於像遍歷小型陣列這樣的簡單操作,無需使用複雜的遞迴函式。
語法
<script async src = "script.js"></script>
實現 async 屬性的優勢
在載入大型 JavaScript 檔案時,async 屬性可能很有用。當 JavaScript 檔案正在下載時,它指示瀏覽器可以繼續解析 HTML 檔案。
因此,瀏覽器可以更快地開始呈現專案,從而可以減少頁面的感知載入時間。
實現 async 屬性的劣勢
Async 可能會違反渲染阻止 CSS 規則,這是其主要劣勢之一。此規則對於確保頁面正確載入並且在 JavaScript 檔案載入時不顯示為空至關重要。如果使用 async,則 CSS 檔案將在 JavaScript 檔案開始載入後立即下載,如果 JavaScript 檔案很大或載入時間很長,這可能會出現問題。
Async 還有一個缺點,即會減慢網站上其他資源(包括圖片)的載入速度。這可能會大大延長頁面整體載入時間。
延遲
defer 屬性指示瀏覽器避免篡改 HTML 解析,並且僅在所有 HTML 標籤都已正確解釋後才執行指令碼檔案。每當找到具有此屬性的指令碼時,指令碼的下載就會在後臺非同步開始。指令碼下載完成後,僅在 HTML 解析完成後才會執行。
布林值分配給 defer 屬性。當設定 defer 屬性時,指令碼會與頁面處理同時下載,並且僅在頁面完成解析後才執行。僅對於外部指令碼使用 defer 屬性(必須存在 src 屬性才能使用此屬性)。
語法
<script defer src = "script.js"></script>
實現 defer 屬性的優勢
defer 屬性具有一些指令碼標籤可以利用的優勢:
延遲指令碼確保在頁面載入並解析後執行,因此它們不會影響頁面最初的載入速度。
延遲指令碼在頁面完全載入後才解析,因此它們不會阻止其他頁面元素(如影像)的解析。
延遲指令碼可以與頁面其餘部分分開更新,因此開發人員無需在更改延遲指令碼時重新解析和重新渲染整個頁面。
實現 defer 屬性的劣勢
一個是頁面載入時間延遲的可能性。如果您的許多指令碼使用 defer,則您的頁面可能會載入得更慢,因為它們可能都在嘗試同時載入。
較舊的瀏覽器可能不支援 defer,這是另一個缺點;因此,某些使用者可能甚至看不到您的指令碼載入。
最後但並非最不重要的是,某些使用者指令碼和擴充套件型別可能會遇到 async 的問題。某些使用者指令碼和擴充套件依賴於在頁面載入後更改 DOM 的能力,但是如果使用了 async,它們可能無法做到這一點,因為在它們執行時 DOM 可能尚未載入。
檢視以下視覺化效果,以更好地瞭解常規、非同步和延遲指令碼標籤之間的區別: