淺談async、defer以普通script加載的區(qū)別
如果用一張圖片詮釋這幾種script加載的特點,應該是這樣的:
結合圖片我們可以將三種方式的特點總結如下:
<script>
: 當HTML解析過程中遇到script標簽時,瀏覽器中斷HTML解析,隨即下載script文件,完成后立即執(zhí)行script,執(zhí)行完成后再繼續(xù)HTML解析<script async>
: 當HTML解析過程中遇到script標簽時,不會中斷HTML解析,同時并行下載script文件,下載完成后中斷HTML解析并執(zhí)行script,執(zhí)行完成后再繼續(xù)HTML解析(script的執(zhí)行順序不一定按照script標簽的出現順序,而是取決于script下載完成的順序)<script defer>
: 當HTML解析過程中遇到script標簽時,不會中斷HTML解析,同時并行下載script文件,直到HTML解析完成再執(zhí)行script(script的執(zhí)行順序與script標簽出現順序一致)
我們可以通過一個小項目驗證上面的結論。
index.html:
<!DOCTYPE html><html lang="en"><head> <script> console.time("timer"); console.timeLog("timer", "--- Start parsing HTML"); document.addEventListener("DOMContentLoaded", function () { console.timeLog("timer", "--- Document loaded"); }); </script></head><body> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Explicabo harum velit itaque assumenda, quibusdam obcaecati suscipit quasi odit accusantium soluta qui, debitis quae iusto? Nobis ratione ut nesciunt a minima. </p> <!-- 此處省略500行重復元素 --> <script>console.timeLog("timer", "--- Start loading 1.js")</script> <script src="./1.js"></script> <script>console.timeLog("timer", "--- Start loading 2.js")</script> <script src="./2.js"></script> <script>console.timeLog("timer", "--- Start loading 3.js")</script> <script src="./3.js"></script> <!-- 此處省略1500行重復元素 --> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit. Explicabo harum velit itaque assumenda, quibusdam obcaecati suscipit quasi odit accusantium soluta qui, debitis quae iusto? Nobis ratione ut nesciunt a minima. </p> <script> console.timeLog("timer", "--- End parsing HTML") </script></body></html>
1.js:
const text1 = ` // 超長文本`text1.split(" ");console.timeLog("timer", "--- 1.js excuted");
2.js:
const text2 = ` // 超長文本`text2.split(" ");console.timeLog("timer", "--- 2.js excuted");
3.js:
const text3 = ` // 超長文本`text3.split(" ");console.timeLog("timer", "--- 3.js excuted");
我們分別使用普通、async和defer的方式加載1.js、2.js、3.js,觀察控制臺的打印結果:
普通:
結論:script出現會中斷HTML加載,且script會順序的加載、執(zhí)行,所有script執(zhí)行完成后再解析HTML。
Async:
結論:HTML解析和script下載同步進行,script執(zhí)行會中斷HTML解析;script執(zhí)行順序和tag出現順序不一定相同;script可能會在document loaded之后執(zhí)行。
Defer:
結論:HTML解析和script下載同步進行;script會在HTML解析完成后和document loaded之前執(zhí)行,且執(zhí)行順序和tag出現順序一致。
由以上實驗可知:如果使用普通方式時通常建議將script放到<body>
的最后,以免阻塞HTML解析影響網頁打開速度。而defer相對于async更具優(yōu)勢,不會阻塞HTML解析且script的執(zhí)行順序可以預測,有一些需要預先下載執(zhí)行的script可以使用defer的方式在<head>
中引用。
到此這篇關于淺談async、defer以普通script加載的區(qū)別的文章就介紹到這了,更多相關async、defer以及普通script加載內容請搜索以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持!
相關文章:
1. SpringBoot的DeferredResult案例:DeferredResult的超時處理方式2. Python協程asyncio模塊的演變及高級用法3. 解決SpringBoot中使用@Async注解失效的問題4. Python并發(fā)concurrent.futures和asyncio實例5. SpringBoot項目@Async方法問題解決方案6. spring boot使用@Async異步注解的實現原理+源碼7. python asyncio 協程庫的使用8. python 使用事件對象asyncio.Event來同步協程的操作9. springboot實現異步調用@Async的示例10. python中使用asyncio實現異步IO實例分析