讓你輕鬆看懂defer和async
阿新 • • 發佈:2022-03-30
defer和async產生的原因
HTML 網頁中,瀏覽器通過<script>標籤載入 JavaScript 指令碼。 <!-- 頁面內嵌的指令碼 --> <script type="application/javascript"> // module code </script> <!-- 外部指令碼 --> <script type="application/javascript" src="path/to/myModule.js"> </script> 由於瀏覽器指令碼的預設語言是 JavaScript。 因此type="application/javascript"是可以省略。 預設情況下,瀏覽器是同步載入 JavaScript 指令碼. 就是說渲染引擎遇到<script>標籤就會停下來,等到執行完指令碼,再繼續向下渲染。 如果是外部指令碼,還必須加入指令碼下載的時間。 如果指令碼體積很大,下載和執行的時間就會很長。 因此造成瀏覽器堵塞,使用者會感覺到瀏覽器“卡死”,使用者體驗不好 所以瀏覽器允許指令碼非同步載入,下面就是兩種非同步載入的語法。 <script src="path/to/myModule.js" defer></script> <script src="path/to/myModule.js" async></script>
defer和async的簡單介紹
<script>標籤上有defer或async屬性,指令碼就會非同步載入。
渲染引擎遇到這一行命令,就會開始下載外部指令碼.
但不會等它下載和執行,而是直接執行後面的命令。
defer與async的區別是[面試題]
defer要等到整個頁面在記憶體中正常渲染結束(DOM 結構完全生成,以及其他指令碼執行完成),才會執行; async一旦下載完,渲染引擎就會中斷渲染,執行這個指令碼以後,再繼續渲染。 一句話,defer是“渲染完再執行”,async是“下載完就執行”。 另外,如果有多個defer指令碼,會按照它們在頁面出現的順序載入, 而多個async指令碼是不能保證載入順序的。
ES6中script標籤module的作用
瀏覽器對於帶有type="module"的<script>,都是非同步載入。 不會造成堵塞瀏覽器的。 即等到整個頁面渲染完,再執行模組指令碼, 等同於打開了<script>標籤的defer屬性。 用程式碼來描述 <script type="module" src="./foo.js"></script> <!-- 等同於 --> <script type="module" src="./foo.js" defer></script> 如果網頁有多個<script type="module">,它們會按照在頁面出現的順序依次執行。 <script>標籤的async屬性也可以開啟,這時只要載入完成, 渲染引擎就會中斷渲染立即執行。執行完成後,再恢復渲染。 <script type="module" src="./foo.js" async></script> 一旦使用了async屬性, <script type="module">就不會按照在頁面出現的順序執行, 而是隻要該模組載入完成,就執行該模組。