script標簽中的async、defer屬性


Script標簽是我們常用的引用js腳本的一種方式。

擼代碼的時候,我們常常只寫src屬性,直接忽略其他屬性。

最近發現了2個可以利用的屬性:async、defer。

顧名思義async就是異步,在不影響其他資源加載的同時,異步加載這個文件;defer就是延遲加載。

下面是高三上的解釋:

Async: 可選屬性。表示應該立即下載腳本,但不應妨礙頁面中的其他操作,比如下載其他資源或等待加載其他腳本。只對外部腳本文件有效(寫在html文件中的js代碼,添加此屬性無效,仍按代碼加載順序執行)。
Defer: 可選屬性。標識腳本可以延遲到文檔完全被解析和顯示之后再執行。只對外部腳本文件有效。

 

是否真的如上所述,下面我們用個demo來驗證一下。

Html代碼:

進入的js文件中,同文件序號分別console.log,1,2,3,4,5,6;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>test1 test2</h1>
</body>
<script defer>   console.log(0) </script>
<script src='js1.js'></script>
<script src='js2.js'></script>
<script src='js3.js'></script>
<script src='js4.js'></script>
<script src='js5.js'></script>
<script src='js6.js'></script>
</html>

 

在瀏覽器中打開這個html文件,我們可以看到6個js文件按照順序加載。

    

 

Ok.現在我給js1文件加上defer屬性,看看。

<script defer src='js1.js'></script>

 

實驗證明:

js文件依然按照書寫順序加載。

但是在控制台可以看到,js1文件的代碼是最后執行的

   

 

那我們還原代碼,給js6文件加上async屬性試試,看看會不會第一個輸出6

<script async src='js6.js'></script>

 

很遺憾,實時並沒有按照預想的那樣輸出6,0,1,2,3,4,5

 

 

如上圖代碼還是按照順序執行了,為什么defer生效了,async沒生效呢?

我們換個文件試試,給中間位置的某個文件添加async屬性。我給js3加了async屬性后,代碼執行順序發生了如下變化:

 

 

那么問題又來了,為什么不是想象中的那個順序:3,0,1,2,4,5,6

下面我們來分析一下原因

1,為什么async屬性加到最后一個script標簽中無效?

2,為什么添加了async屬性的代碼不是優先執行的?

我們都知道,js是按照書寫順序加載,按照書寫順序執行的。文件加載之后,程序便開始解析文件中的代碼。

因此添加了async屬性的文件,需要加載到這個文件位置的時候才會生效,js6已經是最后一個文件了,最后一個加載的文件中的代碼自然就最后執行,因此看起來async在我們的第一個demo中沒有生效。

Async是異步加載,而不是優先加載,因此js3文件添加了async屬性后,當文件加載到js3,同時開始加載js3之后的文件,於是便出現了上圖0,1,2,4,3,5,6的結果,當然這個結果不是必然的,因為我們的demo里面的代碼非常簡短,如果js4中的代碼邏輯復雜,那么結果可能任然是0,1,2,3,4,5,6。

 

說到這里,大家明白async和defer的原理了嗎?

那么什么場景下可以用到這些屬性呢?

比如有些第三方庫,要求在header中引入(這就意味着第三方插件庫會優先加載),但是我們並不需要在頁面加載之初就用到這個插件。那么我們可以加上defer屬性使之最后加載。同理,如果頁面加載的同時需要用到第三方插件,那么我們引用的時候可以加async屬性,這樣網站內的資源就可以與插件資源異步加載。這中方法會給網站其他資源的加載節省出一些時間,不失為一種頁面優化的方法。

 

參考資料:

JavaScript高級程序設計(第3版)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找 js之script屬性async與defer script標簽屬性sync和defer script標簽里的defer屬性 JS script腳本async和defer的區別 script標簽的crossorigin屬性 JavaScript異步加載的三種方式——async和defer、動態創建script defer 和 async 的區別 如何將 JavaScript 代碼添加到網頁中,以及