script標(biāo)簽中的async與defer用法
發(fā)表時間:2023-12-27 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]script標(biāo)簽用于加載腳本與執(zhí)行腳本,在前端開發(fā)中可以說是非常重要的標(biāo)簽了。直接使用script腳本的話,html會按照順序來加載并執(zhí)行腳本,在腳本加載&執(zhí)行的過程中,會阻塞后續(xù)的DOM渲染,F(xiàn)在大家習(xí)慣于在頁面中引用各種的第三方腳本,如果第三方服務(wù)商出現(xiàn)了一些小問題,比如延遲之類的,就...
script
標(biāo)簽用于加載腳本與執(zhí)行腳本,在前端開發(fā)中可以說是非常重要的標(biāo)簽了。
直接使用script
腳本的話,html
會按照順序來加載并執(zhí)行腳本,在腳本加載&執(zhí)行的過程中,會阻塞后續(xù)的DOM
渲染。
現(xiàn)在大家習(xí)慣于在頁面中引用各種的第三方腳本,如果第三方服務(wù)商出現(xiàn)了一些小問題,比如延遲之類的,就會使得頁面白屏。
好在script
提供了兩種方式來解決上述問題,async
和defer
,這兩個屬性使得script
都不會阻塞DOM
的渲染。
但既然會存在兩個屬性,那么就說明,這兩個屬性之間肯定是有差異的。
defer
如果script
標(biāo)簽設(shè)置了該屬性,則瀏覽器會異步的下載該文件并且不會影響到后續(xù)DOM
的渲染;
如果有多個設(shè)置了defer
的script
標(biāo)簽存在,則會按照順序執(zhí)行所有的script
;
defer
腳本會在文檔渲染完畢后,DOMContentLoaded
事件調(diào)用前執(zhí)行。
我們做了一個測試頁面,頁面中包含了兩個script
標(biāo)簽的加載,給他們都加上defer
標(biāo)識。
P.S. 為了更直觀,我們給script1.js
添加了1s
的延遲,給script2.js
添加了2s
的延遲。
下圖是頁面加載的過程&script
腳本的輸出順序。
不難看出,雖然script1
加載用時雖然比script2
短,但因為defer
的限制,所以Ta只能等前邊的腳本執(zhí)行完畢后才能執(zhí)行。
async
async
的設(shè)置,會使得script
腳本異步的加載并在允許的情況下執(zhí)行
async
的執(zhí)行,并不會按著script
在頁面中的順序來執(zhí)行,而是誰先加載完誰執(zhí)行。
我們修改測試頁面如下:
遂得到了如下的結(jié)果,頁面加載時長上,并沒有什么變化,畢竟都是異步加載的腳本。
但是我們可以看到一個小細(xì)節(jié),DOMContentLoaded
事件的觸發(fā)并不受async
腳本加載的影響,在腳本加載完之前,就已經(jīng)觸發(fā)了DOMContentLoaded
。
我們接著修改測試頁面。加載一個沒有延遲的script
腳本,使得腳本可以即時的加載完畢。
我們要測試一下,如果async
腳本加載的足夠快,是否會在DOMContentLoaded
之前就執(zhí)行(這個實驗是基于對async
的描述“在允許的情況下執(zhí)行”的論證)。
同時為了保證測試的穩(wěn)定性,我們在script
腳本引入的后邊添加了數(shù)千個空的p
節(jié)點,用來延長文檔的渲染時間。
執(zhí)行結(jié)果不出所料,如果給async
一定的時間,是有可能在DOMContentLoaded
事件之前就執(zhí)行的。
P.S. 從上圖中左上角的火焰圖中,我們也能看到,出現(xiàn)了多段的藍(lán)色(更新:晚上寫的時候懵了,紫色的才是渲染,藍(lán)色的是解析)文檔渲染。以及下邊Console
的順序。
說明的確,async
的執(zhí)行是加載完成就會去執(zhí)行,而不像defer
那樣要等待所有的腳本加載完后按照順序執(zhí)行。
畫幾張圖簡要說明
網(wǎng)上有了不少這種類似的圖,但是基本都是拿一個script就舉例的
未免太過寒酸,so咱們來一個豪華版,來畫一下多個腳本加載時的甘特圖
就像近年來各大手機廠商,出新機都喜歡來一個X+X plus
拿四個不同的顏色來標(biāo)明各自代表的含義
普通script
文檔解析的過程中,如果遇到script
腳本,就會停止頁面的渲染進(jìn)行下載(但是并不會影響后續(xù)的解析,解析和渲染是兩碼事兒)。
資源的下載是在解析過程中進(jìn)行的,雖說script1
腳本會很快的加載完畢,但是他前邊的script2
并沒有加載&執(zhí)行,所以他只能處于一個掛起的狀態(tài),等待script2
執(zhí)行完畢后再執(zhí)行。
當(dāng)這兩個腳本都執(zhí)行完畢后,才會繼續(xù)渲染頁面。
defer
文檔解析時,遇到設(shè)置了defer
的腳本,就會在后臺進(jìn)行下載,但是并不會阻止文檔的渲染,當(dāng)頁面解析&渲染完畢后。
會等到所有的defer
腳本加載完畢并按照順序執(zhí)行,執(zhí)行完畢后會觸發(fā)DOMContentLoaded
事件。
async
async
腳本會在加載完畢后執(zhí)行。
async
腳本的加載不計入DOMContentLoaded
事件統(tǒng)計,也就是說下圖兩種情況都是有可能發(fā)生的
推薦的應(yīng)用場景
defer
如果你的腳本代碼依賴于頁面中的DOM
元素(文檔是否渲染完畢),或者被其他腳本文件依賴。
例:
評論框
代碼語法高亮
polyfill.js
async
如果你的腳本并不關(guān)心頁面中的DOM
元素(文檔是否渲染完畢),并且也不會產(chǎn)生其他腳本需要的數(shù)據(jù)
以上就是script標(biāo)簽中的async和defer用法的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
網(wǎng)站建設(shè)是一個廣義的術(shù)語,涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護(hù)的網(wǎng)站。