首頁  >  文章  >  web前端  >  script標籤中的async和defer用法

script標籤中的async和defer用法

一个新手
一个新手原創
2017-10-18 09:27:302053瀏覽

script標籤用來載入腳本與執行腳本,在前端開發中可以說是非常重要的標籤了。
直接使用script腳本的話,html會按照順序來載入並執行腳本,在腳本載入&執行的過程中,會阻塞後續的DOM渲染。

現在大家習慣在頁面中引用各種的第三方腳本,如果第三方服務商出現了一些小問題,例如延遲之類的,就會使得頁面白屏。
好在script提供了兩種方式來解決上述問題,asyncdefer,這兩個屬性使得script都不會阻塞DOM的渲染。
但既然會存在兩個屬性,那就說明,這兩個屬性之間一定是有差異的。

defer

如果script標籤設定了該屬性,則瀏覽器會異步的下載該檔案並且不會影響到後續DOM的渲染;
如果有多個設定了deferscript標籤存在,則會依照順序執行所有的script;
defer腳本會在文件渲染完畢後,DOMContentLoaded事件呼叫前執行。

我們做了一個測試頁面,頁面中包含了兩個script標籤的加載,給他們都加上defer標識。
P.S. 為了更直觀,我們為script1.js新增了1s的延遲,新增了2s 的延遲。
下圖是頁面載入的過程&script標籤中的async和defer用法script
腳本的輸出順序。 不難看出,雖然script1
載入用時雖然比script2短,但因為defer的限制,所以Ta只能等前邊的腳本執行完畢後才能執行。
script標籤中的async和defer用法
script標籤中的async和defer用法async

async

的設置,會使得script腳本異步的載入並在允許的情況下執行async
的執行,並不會按著script在頁面中的順序來執行,而是誰先載入完誰執行。

我們修改測試頁面如下:


遂得到如下的結果,頁面載入時長上,並沒有什麼變化,畢竟都是非同步載入的腳本。 script標籤中的async和defer用法但是我們可以看到一個小細節,

DOMContentLoaded事件的觸發並不受async腳本加載的影響,在腳本加載完之前,就已經觸發了DOMContentLoaded
script標籤中的async和defer用法
script標籤中的async和defer用法
script標籤中的async和defer用法

我們接著修改測試頁面。載入一個沒有延遲的script腳本,使得腳本可以即時的載入完畢。
我們要測試一下,如果async腳本載入的夠快,是否會在DOMContentLoaded之前就執行(這個實驗是基於對async的描述「在允許的情況下執行」的論點)。
同時為了確保測試的穩定性,我們在script腳本引入的後邊添加了數千個空的p節點,用來延長文件的渲染時間。
script標籤中的async和defer用法
執行結果不出所料,如果給async一定的時間,是有可能在DOMContentLoaded事件之前就執行的。
script標籤中的async和defer用法
P.S. 從上圖中左上角的火焰圖中,我們也能看到,出現了多段的藍色(更新:晚上寫的時候懵了,紫色的才是渲染,藍色的是解析)文檔渲染。以及下邊Console的順序。
說明的確,async的執行是載入完成就會去執行,而不是像defer那樣要等待所有的腳本載入完後依照順序執行。

畫幾張圖簡單說明

網路上有了不少這種類似的圖,但是基本上都是拿一個script就舉例的
未免太過寒酸, so咱們來一個豪華版,來畫一下多個腳本加載時的甘特圖
就像近年來各大手機廠商,出新機都喜歡來一個X+X plus

拿四個不同的顏色來標示各自代表的意義
script標籤中的async和defer用法

在普通script

#文件解析的過程中,如果遇到script#腳本,就會停止頁面的渲染進行下載(但是並不會影響後續的解析,解析和渲染是兩碼事兒)。
資源的下載是在解析過程中進行的,雖然說script1腳本會很快的載入完畢,但是他前邊的script2並沒有載入&執行,所以他只能處於一個掛起的狀態,等待script2執行完畢後再執行。
當這兩個腳本都執行完畢後,才會繼續渲染頁面。
script標籤中的async和defer用法

defer

文檔解析時,遇到設定了defer的腳本,就會在後台進行下載,但是並不會阻止文檔的渲染,當頁面解析&渲染完畢後。
會等到所有的defer腳本載入完畢並按照順序執行,執行完畢後會觸發DOMContentLoaded事件。
script標籤中的async和defer用法

async

async腳本會在載入完畢後執行。
async腳本的載入不計入DOMContentLoaded事件統計,也就是說下圖兩種情況都是有可能發生的

script標籤中的async和defer用法
script標籤中的async和defer用法

推薦的應用程式場景

defer

如果你的腳本程式碼依賴頁面中的DOM元素(文件是否渲染完畢),或者被其他腳本檔案依賴。
範例:

  1. 評論方塊

  2. #程式碼語法高亮

  3. #程式碼語法高亮

polyfill.js

######async######如果你的腳本並不關心頁面中的###DOM###元素(文件是否渲染完畢),也不會產生其他腳本所需的資料###

以上是script標籤中的async和defer用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn