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場景, 多個(gè)defer腳本不一定會(huì)按照順序執(zhí)行, 最佳實(shí)踐是只使用一個(gè)defer腳本。
defer推薦使用場景:
如果你的腳本代碼依賴于頁面中的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
事件。這種場景, async腳本的執(zhí)行如果慢, 會(huì)延遲DOMContentLoaded
事件的觸發(fā)時(shí)間。 - 如果async腳本下載較慢, 當(dāng)async還在下載時(shí), 文檔的解析渲染已完成,這時(shí)不會(huì)等待async的下載, 會(huì)直接觸發(fā)
DOMContentLoaded
事件。這種場景, 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推薦使用場景:
如果你的腳本并不關(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)文章
ES6新特性六:promise對(duì)象實(shí)例詳解
這篇文章主要介紹了ES6新特性之promise對(duì)象,結(jié)合實(shí)例形式詳細(xì)分析了promise對(duì)象的功能、狀態(tài)、使用方法與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04js實(shí)現(xiàn)不提交表單獲取單選按鈕值的方法
這篇文章主要介紹了js實(shí)現(xiàn)不提交表單獲取單選按鈕值的方法,涉及javascript鼠標(biāo)事件及頁面元素屬性操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08javascript實(shí)現(xiàn)搶購倒計(jì)時(shí)程序
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)搶購倒計(jì)時(shí)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08javascript仿XP關(guān)機(jī)效果的彈出窗口功能
javascript仿XP關(guān)機(jī)效果的彈出窗口功能...2007-10-10javascript+ajax實(shí)現(xiàn)產(chǎn)品頁面加載信息
本文給大家分享的是使用javascript結(jié)合ajax實(shí)現(xiàn)產(chǎn)品頁面無刷新加載信息的代碼,非常的簡單實(shí)用,有需要的小伙伴可以參考下。2015-07-07