在HTML中會(huì)遇到一下三類script
<script src=""></script>
<script src="" async></script>
<script src="" defer></script>
那么這三類有什么區(qū)別呢?
script
瀏覽器在解析HTML代碼的時(shí)候,如果遇到一個(gè)沒有任何屬性的script標(biāo)簽藏姐,就會(huì)暫停解析HTML乖篷,先發(fā)送網(wǎng)絡(luò)請(qǐng)求獲取該js腳本的代碼并解析厅篓,然后讓js引擎執(zhí)行該代碼,當(dāng)js代碼執(zhí)行完畢后恢復(fù)解析捶码。整個(gè)過程如下圖所示:
可以看到羽氮,script阻塞了瀏覽器對(duì)HTML的解析,如果獲取js腳本的網(wǎng)絡(luò)請(qǐng)求遲遲得不到響應(yīng)后者js腳本執(zhí)行時(shí)間過長惫恼,都會(huì)導(dǎo)致白屏用戶看不到內(nèi)容档押。
async script
async表示異步,但瀏覽器遇到帶有async屬性的script時(shí)祈纯,請(qǐng)求該腳本的網(wǎng)絡(luò)請(qǐng)求是異步的令宿,不會(huì)阻塞瀏覽器解析HTML,一旦網(wǎng)絡(luò)請(qǐng)求回來之后腕窥,分一下兩種情況:
-此時(shí)HTML還沒有解析完粒没,瀏覽器會(huì)暫停解析HTML,先讓js引擎執(zhí)行代碼簇爆,執(zhí)行完畢后再解析HTML癞松;
-此時(shí)HTML代碼解析完成,直接執(zhí)行js代碼冕碟;
所以async是不可控的拦惋,執(zhí)行時(shí)間不確定,如果在異步j(luò)s腳本中獲取某個(gè)DOM元素安寺,有可能獲取到也有可能獲取不到而且如果存在多個(gè)async的時(shí)候厕妖,他們之間的執(zhí)行順序也是不確定的,完全依賴網(wǎng)絡(luò)傳輸結(jié)果挑庶,誰先到執(zhí)行誰言秸。
defer script
defer表示延遲,當(dāng)瀏覽器遇到帶有defer屬性的script的時(shí)候迎捺,獲取該腳本的網(wǎng)絡(luò)請(qǐng)求也是異步的举畸,不會(huì)阻塞瀏覽器解析HTML,一旦網(wǎng)絡(luò)請(qǐng)求回來之后凳枝,如果此時(shí)HTML代碼還沒有解析完抄沮,瀏覽器不會(huì)暫停解析HTML代碼并執(zhí)行js代碼,而是等待HTML解析完畢以后再執(zhí)行js代碼岖瑰,如圖:
如果存在多個(gè)defer script標(biāo)簽叛买,瀏覽器會(huì)保證他們按照在HTML中出現(xiàn)的順序執(zhí)行,不會(huì)破壞js腳本之間的依賴關(guān)系蹋订。
總結(jié):
script 標(biāo)簽 JS 執(zhí)行順序 是否阻塞解析 HTML
<script> 在 HTML 中的順序 阻塞
<script async> 網(wǎng)絡(luò)請(qǐng)求返回順序 可能阻塞率挣,也可能不阻塞
<script defer> 在 HTML 中的順序 不阻塞