script標(biāo)簽中的defer和async使用技巧說明
script標(biāo)簽用于加載腳本與執(zhí)行腳本,在前端開發(fā)中可以說是非常重要的標(biāo)簽了。
直接使用script腳本的話,html會(huì)按照順序來加載并執(zhí)行腳本,在腳本加載&執(zhí)行的過程中,會(huì)阻塞后續(xù)的DOM渲染。

普通script:
- 文檔解析的過程中,如果遇到
script腳本,停止頁面的解析渲染,下載script腳本。 - 如果是多個(gè)script腳本, 近似于同時(shí)并行下載script腳本。(雖然說是遇到script腳本, 就停止后面標(biāo)簽的解析渲染; 但chrome做了優(yōu)化, 遇到script腳本, 會(huì)快速的查看后邊有沒有需要下載其他資源的, 一起并行下載, 為了節(jié)省一部分下載的時(shí)間。)
- 不論script腳本哪個(gè)先下載好, 都按照html中的先后順序依此執(zhí)行。 即如果后面的script腳本先下載好, 要等前面的script腳本下載好并執(zhí)行后, 才能執(zhí)行。
- 執(zhí)行script腳本時(shí), 也是停止頁面的解析渲染。
- 執(zhí)行完script腳本, 繼續(xù)頁面的解析渲染。
- 執(zhí)行完script腳本和頁面解析渲染完, 才會(huì)依此觸發(fā)DOMContentLoaded, loaded事件

普通script總結(jié):
- 1.普通script的下載和執(zhí)行都阻塞頁面的解析渲染。
- 2. 多個(gè)script的下載是并行, 但按照頁面中順序依此執(zhí)行。
- 3. 考慮到不支持defer和async的老瀏覽器, 最佳實(shí)踐是script放在body底部, 避免阻塞頁面的解析渲染。
- 4.執(zhí)行完script腳本, 繼續(xù)頁面的解析渲染。頁面解析渲染完, 才會(huì)觸發(fā)DOMContentLoaded。所以普通script腳本的下載和執(zhí)行如果慢, 會(huì)延遲
DOMContentLoaded事件的觸發(fā)時(shí)間。

defer:
- 文檔解析時(shí),遇到設(shè)置了
defer的script腳本,就會(huì)在后臺(tái)進(jìn)行下載,下載并不會(huì)阻止文檔的解析渲染。 - 如果是多個(gè)設(shè)置了defer的script腳本, 近似于同時(shí)并行下載defer腳本。
- 當(dāng)頁面解析渲染完畢后,會(huì)等到所有的
defer腳本下載完畢并按照順序執(zhí)行,執(zhí)行完畢后會(huì)觸發(fā)DOMContentLoaded事件。 - 如果defer腳本下載較快, 會(huì)等到頁面解析渲染完畢后, 才按照順序執(zhí)行defer腳本。執(zhí)行完畢后會(huì)觸發(fā)
DOMContentLoaded事件。 - 如果defer腳本下載較慢, 在下載完前,頁面解析渲染已完畢; 等defer腳本下載完后,才按照順序執(zhí)行defer腳本。執(zhí)行完畢后會(huì)觸發(fā)
DOMContentLoaded事件。
defer 總結(jié):
- 1.
defer腳本的下載和執(zhí)行都不會(huì)阻塞頁面的解析渲染。因?yàn)榈鹊巾撁娴慕馕鲣秩就戤吅?defer腳本才執(zhí)行, 所以defer腳本執(zhí)行也不會(huì)阻塞頁面的解析渲染。 - 2. 多個(gè)
defer腳本的下載是并行, 但按照順序依此執(zhí)行。 - 3. 等頁面的解析渲染完畢后,觸發(fā)
DOMContentLoaded事件前,defer腳本才依次執(zhí)行。 所以defer腳本的下載和執(zhí)行如果慢, 會(huì)延遲DOMContentLoaded事件的觸發(fā)時(shí)間。 - 4. 考慮有的瀏覽器不支持 defer場(chǎng)景, 多個(gè)defer腳本不一定會(huì)按照順序執(zhí)行, 最佳實(shí)踐是只使用一個(gè)defer腳本。
defer推薦使用場(chǎng)景:
如果你的腳本代碼依賴于頁面中的DOM元素(文檔是否解析完畢),或者被其他腳本文件依賴。
例:
- 1. 評(píng)論框
- 2.代碼語法高亮
- 3.
polyfill.js

async:
- 文檔解析時(shí),遇到設(shè)置了
async的script腳本,就會(huì)在后臺(tái)進(jìn)行下載,下載并不會(huì)阻止文檔的解析渲染。 - 如果是多個(gè)設(shè)置了async的script腳本, 近似于同時(shí)并行下載async腳本。
- async腳本的執(zhí)行會(huì)阻止文檔的解析渲染。
- 哪個(gè)async腳本先下載完, 就立刻執(zhí)行,執(zhí)行時(shí)阻止文檔的解析渲染。async腳本執(zhí)行順序不按照頁面中的腳本先后順序。
async腳本的下載和執(zhí)行不計(jì)入DOMContentLoaded事件統(tǒng)計(jì)。- 因async腳本下載不阻塞文檔的解析渲染;如果async腳本下載較快, 趁async腳本下載很短時(shí)間內(nèi), 文檔的解析渲染未完成, async下載后立即執(zhí)行,執(zhí)行時(shí)會(huì)阻塞文檔的解析渲染; 執(zhí)行后, 繼續(xù)文檔的解析渲染, 等頁面的解析渲染完畢后,觸發(fā)
DOMContentLoaded事件。這種場(chǎng)景, async腳本的執(zhí)行如果慢, 會(huì)延遲DOMContentLoaded事件的觸發(fā)時(shí)間。 - 如果async腳本下載較慢, 當(dāng)async還在下載時(shí), 文檔的解析渲染已完成,這時(shí)不會(huì)等待async的下載, 會(huì)直接觸發(fā)
DOMContentLoaded事件。這種場(chǎng)景, async腳本的下載和執(zhí)行不會(huì)延遲DOMContentLoaded事件的觸發(fā)時(shí)間。
async總結(jié):
- 1.
async腳本的下載不會(huì)阻塞頁面的解析渲染。async腳本的執(zhí)行會(huì)阻塞頁面的解析渲染。 - 2. 多個(gè)
async腳本的下載是并行, 但執(zhí)行不按照頁面中的腳本先后順序。哪個(gè)async腳本先下載完, 哪個(gè)async腳本就先立刻執(zhí)行。 - 3.
async腳本的下載和執(zhí)行不計(jì)入DOMContentLoaded事件統(tǒng)計(jì)。 - 4. async腳本的執(zhí)行有可能在
DOMContentLoaded事件前, 也有可能在DOMContentLoaded事件后。 - 5. 當(dāng)async腳本的執(zhí)行在
DOMContentLoaded事件前時(shí),async腳本的執(zhí)行時(shí)間才會(huì)影響DOMContentLoaded事件的觸發(fā)時(shí)間。又因?yàn)槟_本的執(zhí)行時(shí)間一般都比較短, 所以可以認(rèn)為async腳本基本不影響DOMContentLoaded事件的觸發(fā)時(shí)間。
async推薦使用場(chǎng)景:
如果你的腳本并不關(guān)心頁面中的DOM元素(文檔是否解析完畢),并且也不會(huì)產(chǎn)生其他腳本需要的數(shù)據(jù)。
例:
1. 百度統(tǒng)計(jì)和Google Analytics


普通script, defer, async同時(shí)存在頁面中:
- 1. 普通script執(zhí)行完, 繼續(xù)頁面解析渲染;頁面解析渲染完, 才觸發(fā)
DOMContentLoaded事件。 - 2.
defer腳本是在頁面解析渲染完,DOMContentLoaded事件的觸發(fā)前, 才執(zhí)行defer腳本。 - 3. 由于1,2這兩點(diǎn), 所以一定先執(zhí)行普通script, 再執(zhí)行defer腳本。
- 4.
async腳本的下載和執(zhí)行不計(jì)入DOMContentLoaded事件統(tǒng)計(jì)。 - 5.
async腳本下載完, 就立刻執(zhí)行, 且多個(gè)async腳本執(zhí)行不按照頁面中的腳本先后順序。
由于4,5這兩點(diǎn), 所以async腳本執(zhí)行與普通script, defer腳本無關(guān), 那個(gè)時(shí)間點(diǎn)都有可能執(zhí)行。
注意:defer,async只對(duì)外聯(lián)script腳本文件有效, 內(nèi)聯(lián)script腳本設(shè)置無效。
以上就是script標(biāo)簽中的defer和async的詳細(xì)內(nèi)容,更多關(guān)于script標(biāo)簽中的defer和async的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Easyui Tree獲取當(dāng)前選擇節(jié)點(diǎn)的所有頂級(jí)父節(jié)點(diǎn)
這篇文章主要介紹了Easyui Tree獲取當(dāng)前選擇節(jié)點(diǎn)的所有頂級(jí)父節(jié)點(diǎn),以及easyUI Tree顯示選中節(jié)點(diǎn)的所有父節(jié)點(diǎn)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-02-02
javascript while語句和do while語句的區(qū)別分析
這篇文章通過實(shí)例代碼較詳細(xì)的給大家介紹了javascript while語句和do while語句的區(qū)別,感興趣的朋友一起看看吧2007-12-12
微信公眾號(hào)生成新浪短網(wǎng)址的實(shí)現(xiàn)(快速生成)
這篇文章主要介紹了微信公眾號(hào)生成新浪短網(wǎng)址的實(shí)現(xiàn)(快速生成),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
JS實(shí)現(xiàn)可拖曳、可關(guān)閉的彈窗效果
這篇文章主要介紹了JS實(shí)現(xiàn)可拖曳、可關(guān)閉的彈窗效果,可實(shí)現(xiàn)點(diǎn)擊文字彈出可拖動(dòng)的窗口,同時(shí)背景出現(xiàn)變暗的遮罩效果,點(diǎn)擊遮罩層即可關(guān)閉彈出,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Bootstrap彈出框modal上層的輸入框不能獲得焦點(diǎn)問題的解決方法
這篇文章主要介紹了Bootstrap彈出框modal上層的輸入框不能獲得焦點(diǎn)問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
微信小程序?qū)崿F(xiàn)滑動(dòng)翻頁效果(完整代碼)
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)滑動(dòng)翻頁效果,本文通過效果圖展示實(shí)例代碼講解的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
微信小程序scroll-view實(shí)現(xiàn)自定義滾動(dòng)條
這篇文章主要為大家詳細(xì)介紹了微信小程序scroll-view實(shí)現(xiàn)自定義滾動(dòng)條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06

