script標(biāo)簽中的defer和async使用技巧說明
script
標(biāo)簽用于加載腳本與執(zhí)行腳本,在前端開發(fā)中可以說是非常重要的標(biāo)簽了。
直接使用script
腳本的話,html
會按照順序來加載并執(zhí)行腳本,在腳本加載&執(zhí)行的過程中,會阻塞后續(xù)的DOM
渲染。
普通script:
- 文檔解析的過程中,如果遇到
script
腳本,停止頁面的解析渲染,下載script腳本。 - 如果是多個script腳本, 近似于同時并行下載script腳本。(雖然說是遇到script腳本, 就停止后面標(biāo)簽的解析渲染; 但chrome做了優(yōu)化, 遇到script腳本, 會快速的查看后邊有沒有需要下載其他資源的, 一起并行下載, 為了節(jié)省一部分下載的時間。)
- 不論script腳本哪個先下載好, 都按照html中的先后順序依此執(zhí)行。 即如果后面的script腳本先下載好, 要等前面的script腳本下載好并執(zhí)行后, 才能執(zhí)行。
- 執(zhí)行script腳本時, 也是停止頁面的解析渲染。
- 執(zhí)行完script腳本, 繼續(xù)頁面的解析渲染。
- 執(zhí)行完script腳本和頁面解析渲染完, 才會依此觸發(fā)DOMContentLoaded, loaded事件
普通script總結(jié):
- 1.普通script的下載和執(zhí)行都阻塞頁面的解析渲染。
- 2. 多個script的下載是并行, 但按照頁面中順序依此執(zhí)行。
- 3. 考慮到不支持defer和async的老瀏覽器, 最佳實踐是script放在body底部, 避免阻塞頁面的解析渲染。
- 4.執(zhí)行完script腳本, 繼續(xù)頁面的解析渲染。頁面解析渲染完, 才會觸發(fā)DOMContentLoaded。所以普通script腳本的下載和執(zhí)行如果慢, 會延遲
DOMContentLoaded
事件的觸發(fā)時間。
defer:
- 文檔解析時,遇到設(shè)置了
defer
的script腳本,就會在后臺進(jìn)行下載,下載并不會阻止文檔的解析渲染。 - 如果是多個設(shè)置了defer的script腳本, 近似于同時并行下載defer腳本。
- 當(dāng)頁面解析渲染完畢后,會等到所有的
defer
腳本下載完畢并按照順序執(zhí)行,執(zhí)行完畢后會觸發(fā)DOMContentLoaded
事件。 - 如果defer腳本下載較快, 會等到頁面解析渲染完畢后, 才按照順序執(zhí)行defer腳本。執(zhí)行完畢后會觸發(fā)
DOMContentLoaded
事件。 - 如果defer腳本下載較慢, 在下載完前,頁面解析渲染已完畢; 等defer腳本下載完后,才按照順序執(zhí)行defer腳本。執(zhí)行完畢后會觸發(fā)
DOMContentLoaded
事件。
defer 總結(jié):
- 1.
defer
腳本的下載和執(zhí)行都不會阻塞頁面的解析渲染。因為等到頁面的解析渲染完畢后,defer腳本才執(zhí)行, 所以defer
腳本執(zhí)行也不會阻塞頁面的解析渲染。 - 2. 多個
defer腳本
的下載是并行, 但按照順序依此執(zhí)行。 - 3. 等頁面的解析渲染完畢后,觸發(fā)
DOMContentLoaded
事件前,defer腳本才依次執(zhí)行。 所以defer腳本的下載和執(zhí)行如果慢, 會延遲DOMContentLoaded
事件的觸發(fā)時間。 - 4. 考慮有的瀏覽器不支持 defer場景, 多個defer腳本不一定會按照順序執(zhí)行, 最佳實踐是只使用一個defer腳本。
defer推薦使用場景:
如果你的腳本代碼依賴于頁面中的DOM
元素(文檔是否解析完畢),或者被其他腳本文件依賴。
例:
- 1. 評論框
- 2.代碼語法高亮
- 3.
polyfill.js
async:
- 文檔解析時,遇到設(shè)置了
async
的script腳本,就會在后臺進(jìn)行下載,下載并不會阻止文檔的解析渲染。 - 如果是多個設(shè)置了async的script腳本, 近似于同時并行下載async腳本。
- async腳本的執(zhí)行會阻止文檔的解析渲染。
- 哪個async腳本先下載完, 就立刻執(zhí)行,執(zhí)行時阻止文檔的解析渲染。async腳本執(zhí)行順序不按照頁面中的腳本先后順序。
async
腳本的下載和執(zhí)行不計入DOMContentLoaded
事件統(tǒng)計。- 因async腳本下載不阻塞文檔的解析渲染;如果async腳本下載較快, 趁async腳本下載很短時間內(nèi), 文檔的解析渲染未完成, async下載后立即執(zhí)行,執(zhí)行時會阻塞文檔的解析渲染; 執(zhí)行后, 繼續(xù)文檔的解析渲染, 等頁面的解析渲染完畢后,觸發(fā)
DOMContentLoaded
事件。這種場景, async腳本的執(zhí)行如果慢, 會延遲DOMContentLoaded
事件的觸發(fā)時間。 - 如果async腳本下載較慢, 當(dāng)async還在下載時, 文檔的解析渲染已完成,這時不會等待async的下載, 會直接觸發(fā)
DOMContentLoaded
事件。這種場景, async腳本的下載和執(zhí)行不會延遲DOMContentLoaded
事件的觸發(fā)時間。
async總結(jié):
- 1.
async
腳本的下載不會阻塞頁面的解析渲染。async
腳本的執(zhí)行會阻塞頁面的解析渲染。 - 2. 多個
async腳本
的下載是并行, 但執(zhí)行不按照頁面中的腳本先后順序。哪個async腳本先下載完, 哪個async腳本就先立刻執(zhí)行。 - 3.
async
腳本的下載和執(zhí)行不計入DOMContentLoaded
事件統(tǒng)計。 - 4. async腳本的執(zhí)行有可能在
DOMContentLoaded
事件前, 也有可能在DOMContentLoaded
事件后。 - 5. 當(dāng)async腳本的執(zhí)行在
DOMContentLoaded
事件前時,async
腳本的執(zhí)行時間才會影響DOMContentLoaded
事件的觸發(fā)時間。又因為腳本的執(zhí)行時間一般都比較短, 所以可以認(rèn)為async腳本基本不影響DOMContentLoaded
事件的觸發(fā)時間。
async推薦使用場景:
如果你的腳本并不關(guān)心頁面中的DOM
元素(文檔是否解析完畢),并且也不會產(chǎn)生其他腳本需要的數(shù)據(jù)。
例:
1. 百度統(tǒng)計和Google Analytics
普通script, defer, async同時存在頁面中:
- 1. 普通script執(zhí)行完, 繼續(xù)頁面解析渲染;頁面解析渲染完, 才觸發(fā)
DOMContentLoaded
事件。 - 2.
defer
腳本是在頁面解析渲染完,DOMContentLoaded
事件的觸發(fā)前, 才執(zhí)行defer腳本。 - 3. 由于1,2這兩點(diǎn), 所以一定先執(zhí)行普通script, 再執(zhí)行defer腳本。
- 4.
async
腳本的下載和執(zhí)行不計入DOMContentLoaded
事件統(tǒng)計。 - 5.
async
腳本下載完, 就立刻執(zhí)行, 且多個async腳本執(zhí)行不按照頁面中的腳本先后順序。
由于4,5這兩點(diǎn), 所以async腳本執(zhí)行與普通script, defer腳本無關(guān), 那個時間點(diǎn)都有可能執(zhí)行。
注意:defer,async只對外聯(lián)script腳本文件有效, 內(nèi)聯(lián)script腳本設(shè)置無效。
以上就是script標(biāo)簽中的defer和async的詳細(xì)內(nèi)容,更多關(guān)于script標(biāo)簽中的defer和async的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript仿XP關(guān)機(jī)效果的彈出窗口功能
javascript仿XP關(guān)機(jī)效果的彈出窗口功能...2007-10-10javascript+ajax實現(xiàn)產(chǎn)品頁面加載信息
本文給大家分享的是使用javascript結(jié)合ajax實現(xiàn)產(chǎn)品頁面無刷新加載信息的代碼,非常的簡單實用,有需要的小伙伴可以參考下。2015-07-07