JS script腳本async和defer的區別


壹 ❀ 引

我在 google recaptcha 谷歌人機身份驗證使用教程 一文中有引用這樣一段外部資源代碼,如下:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

可以看到在script標簽中,存在asyncdefer兩個屬性,首先這兩個屬性並共存,說直白點,你一個都不加,或者加兩個屬性其一,腳本加載規則都會不同,這點我在之前確實沒仔細了解過,導致我在實際開發中遇到了這樣一個問題:

我在同一個頁面需要引用2個script腳本,大致如下:

<script src="https://www.google.com/recaptcha/api.js"></script>
<script src="demo.js"></script>

注意,兩個script腳本都沒有添加asyncdefer屬性,demo.js中包含了谷歌人機驗證的初始化程序,正常來說一定得先加載必要的資源,這樣我的驗證碼才能初始化成功,這就像使用jQuery得先引用jQuery.js是一個道理。

但事實上,因為外網的問題,api.js引用雖然在前面,但下載並不穩定,有時候會出現下載反而比demo.js更晚的情況,這就導致demo.js中的初始化報錯,怎么辦呢?這就得asyncdefer出場了,我們先來了解它們的區別。

貳 ❀ 屬性async、defer與不加的區別

貳 ❀ 壹 不加屬性

引用script腳本,最常見的就是直接引用,不加其它屬性,這種情況瀏覽器會立即下載並執行指定的腳本,一氣呵成,腳本不執行完畢,后面的DOM加載全部給我候着,如下圖:

貳 ❀ 貳 屬性async

了解ajax的同學對於async這個詞一定不陌生,它表示異步,如果script腳本添加了此屬性,瀏覽器會異步下載后立刻同步執行腳本。

說通俗點,腳本下載是異步行為,下載過程中並不影響DOM加載,但一旦腳本下載完畢就會立刻同步執行腳本,此時DOM加載還是得給我等着。如下圖:

貳 ❀ 叄 屬性defer

async一樣屬於異步下載腳本,但不同的地方是,腳本下載完成后並不會立刻執行,而是等到DOM解析完成才會執行腳本,相比async的粗暴,defer明顯更加實用。加載順序如下圖:

現在我們知道了腳本屬性asyncdefer以及不加的區別,回到文章開始的問題,我希望api.js一定在demo.js之前加載完成,不管需要等多久,所以我們可以這樣修改:

<script src="https://www.google.com/recaptcha/api.js" async></script>
<script src="demo.js" defer></script>

那么到這里本文正式結束。


免責聲明!

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



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM