這篇文章來源于JS高級程序設(shè)計(jì)第三版中關(guān)于script標(biāo)簽的介紹绝淡,結(jié)合查閱的資料寫下的學(xué)習(xí)筆記豺旬。
向html頁面中插入javascript代碼的主要方法就是通過script標(biāo)簽奢讨。其中包括兩種形式靠闭,第一種直接在script標(biāo)簽之間插入js代碼斗埂,第二種即是通過src屬性引入外部js文件端衰。由于解釋器在解析執(zhí)行js代碼期間會(huì)阻塞頁面其余部分的渲染叠洗,對于存在大量js代碼的頁面來說會(huì)導(dǎo)致瀏覽器出現(xiàn)長時(shí)間的空白和延遲,為了避免這個(gè)問題旅东,建議把全部的js引用放在標(biāo)簽之前灭抑。
script標(biāo)簽存在兩個(gè)屬性,defer和async抵代,因此script標(biāo)簽的使用分為三種情況:
1.
沒有defer或async屬性腾节,瀏覽器會(huì)立即加載并執(zhí)行相應(yīng)的腳本。也就是說在渲染script標(biāo)簽之后的文檔之前荤牍,不等待后續(xù)加載的文檔元素案腺,讀到就開始加載和執(zhí)行,此舉會(huì)阻塞后續(xù)文檔的加載参淫;
2.
有了async屬性救湖,表示后續(xù)文檔的加載和渲染與js腳本的加載和執(zhí)行是并行進(jìn)行的,即異步執(zhí)行涎才;
3.
有了defer屬性鞋既,加載后續(xù)文檔的過程和js腳本的加載(此時(shí)僅加載不執(zhí)行)是并行進(jìn)行的(異步),js腳本的執(zhí)行需要等到文檔所有元素解析完成之后耍铜,DOMContentLoaded事件觸發(fā)執(zhí)行之前邑闺。
下圖可以直觀的看出三者之間的區(qū)別:
其中藍(lán)色代表js腳本網(wǎng)絡(luò)加載時(shí)間,紅色代表js腳本執(zhí)行時(shí)間棕兼,綠色代表html解析陡舅。
從圖中我們可以明確一下幾點(diǎn):
1.defer和async在網(wǎng)絡(luò)加載過程是一致的,都是異步執(zhí)行的伴挚;
2.兩者的區(qū)別在于腳本加載完成之后何時(shí)執(zhí)行靶衍,可以看出defer更符合大多數(shù)場景對應(yīng)用腳本加載和執(zhí)行的要求灾炭;
3.如果存在多個(gè)有defer屬性的腳本,那么它們是按照加載順序執(zhí)行腳本的颅眶;而對于async蜈出,它的加載和執(zhí)行是緊緊挨著的,無論聲明順序如何涛酗,只要加載完成就立刻執(zhí)行铡原,它對于應(yīng)用腳本用處不大,因?yàn)樗耆豢紤]依賴商叹。