defer和async的區(qū)別

頁面的加載和渲染過程

  1. 瀏覽器通過HTTP協(xié)議請求服務(wù)器,獲取HMTL文檔并開始從上到下解析,構(gòu)建DOM;

  2. 在構(gòu)建DOM過程中,如果遇到外聯(lián)的樣式聲明和腳本聲明,則暫停文檔解析,創(chuàng)建新的網(wǎng)絡(luò)連接,并開始下載樣式文件和腳本文件;

  3. 樣式文件下載完成后,構(gòu)建CSSDOM;腳本文件下載完成后,解釋并執(zhí)行,然后繼續(xù)解析文檔構(gòu)建DOM;

  4. 完成文檔解析后,將DOMCSSDOM進(jìn)行關(guān)聯(lián)和映射,最后將視圖渲染到瀏覽器窗口 。

在這個(gè)過程中,腳本文件的下載和執(zhí)行是與文檔解析同步進(jìn)行,也就是說,它會(huì)阻塞文檔的解析,如果控制得不好,在用戶體驗(yàn)上就會(huì)造成一定程度的影響。

<script src="script.js"></script>

沒有 defer 或 async,瀏覽器會(huì)立即加載并執(zhí)行指定的腳本,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行。

<script async src="script.js"></script>

有 async,加載和渲染后續(xù)文檔元素的過程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)。

<script defer src="myscript.js"></script>

有 defer,加載后續(xù)文檔元素的過程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。

defer

用于開啟新的線程下載腳本文件,并使腳本在文檔解析完成后執(zhí)行。

這個(gè)屬性的用途是表明腳本在執(zhí)行時(shí)不會(huì)影響頁面的構(gòu)造。也就是說,腳本會(huì)被延遲到整個(gè)頁面都解析完畢后再運(yùn)行。因此,在<script>元素中設(shè)置defer屬性,相當(dāng)于告訴瀏覽器立即下載,但延遲執(zhí)行。

HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行,因此第一個(gè)延遲腳本會(huì)先于第二個(gè)延遲腳本執(zhí)行,而這兩個(gè)腳本會(huì)先于DOMContentLoaded事件執(zhí)行。在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會(huì)按照順序執(zhí)行,也不一定會(huì)在DOMContentLoad時(shí)間觸發(fā)前執(zhí)行,因此最好只包含一個(gè)延遲腳本。

async

HTML5新增屬性,用于異步下載腳本文件,下載完畢立即解釋執(zhí)行代碼。

這個(gè)屬性與defer類似,都用于改變處理腳本的行為。同樣與defer類似,async只適用于外部腳本文件,并告訴瀏覽器立即下載文件。但與defer不同的是,標(biāo)記為async的腳本并不保證按照它們的先后順序執(zhí)行。

第二個(gè)腳本文件可能會(huì)在第一個(gè)腳本文件之前執(zhí)行。因此確保兩者之間互不依賴非常重要。指定async屬性的目的是不讓頁面等待兩個(gè)腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。


圖片來源:討論區(qū)地址

藍(lán)色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時(shí)間,這倆都是針對腳本的;綠色線代表 HTML 解析。

也就是說async是亂序的,而defer是順序執(zhí)行,這也就決定了async比較適用于百度分析或者谷歌分析這類不依賴其他腳本的庫。從圖中可以看到一個(gè)普通的<script>標(biāo)簽的加載和解析都是同步的,會(huì)阻塞DOM的渲染,這也就是我們經(jīng)常會(huì)把<script>寫在<body>底部的原因之一,為了防止加載資源而導(dǎo)致的長時(shí)間的白屏,另一個(gè)原因是js可能會(huì)進(jìn)行DOM操作,所以要在DOM全部渲染完后再執(zhí)行。

參考文章

defer和async的區(qū)別
淺談script標(biāo)簽的defer和async
詳解defer和async的原理及應(yīng)用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容