JS中關於async和defer作用與區別

<script src="script.js"></script>
沒有 defer 或 async,瀏覽器會立即加載並執行指定的腳本,“立即”指的是在渲染該 script 標籤之下的文檔元素之前,也就是說不等待後續載入的文檔元素,讀到就加載並執行。

<script async src="script.js"></script>
有 async,加載和渲染後續文檔元素的過程將和 script.js 的加載與執行並行進行(異步)。

<script defer src="myscript.js"></script>
有 defer,加載後續文檔元素的過程將和 script.js 的加載並行進行(異步),但是 script.js 的執行要在所有元素解析完成之後,DOMContentLoaded 事件觸發之前完成。

  • 從實用角度來講,首先把所有腳本都放置到 </body> 之前是最佳實踐,因爲對於舊瀏覽器來說這是唯一的優化選擇,此法可保證非腳本的其他一切元素能夠以最快的速度得到加載和解析。

  • 藍色線代表網絡讀取,紅色線代表執行時間,這倆都是針對腳本的;綠色線代表 HTML 解析。

  • 由圖得知:

  1. defer 和 async 在網絡讀取(下載)這部分是一樣的,都是異步的(相較於 HTML 解析)。
    兩者的差別在於腳本下載完之後何時執行,顯然 defer 是最接近我們對於應用腳本加載和執行的要求的。

  2. 關於 defer,由圖知它是按照加載順序執行腳本的,這一點要善加利用。
    async 則是亂序執行,反正對它來說腳本的加載和執行是緊緊挨着的,所以不管你聲明的順序如何,只要它加載完了就會立刻執行。

  3. async 對於應用腳本的用處不大,因爲它完全不考慮依賴(哪怕是最低級的順序執行),不過它對於那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的,最典型的例子:Google Analytics。


  • 下面來說明一下兩者之間的不同:
      正常情況下,當瀏覽器在解析HTML源文件時如果遇到外部的script,那麼解析過程會暫停,併發送請求來下載script文件,只有script完全下載並執行後纔會繼續執行DOM解析。
      那麼如果一個頁面有很多的外鏈的腳本。放在head中,那麼加載腳本的時候就會阻塞頁面的渲染,出現空白的現象。在簡單的開發環境中可能調整一下js的位置就能解決問題。但是在越來越複雜的開發環境下,如果想調整js腳本的位置可能就要花費大量的時間。所以爲了讓這種成本降低。可以使用defer屬性。
      如果一個script加了defer屬性,即使放在head裏面,它也會在html頁面解析完畢之後再去執行,也就是類似於把這個script放在了頁面底部。
      對於async,這個是html5中新增的屬性,它的作用是能夠異步的加載和執行腳本,不因爲加載腳本而阻塞頁面的加載。一旦加載到就會立刻執行。

  • 兩者的相同點
    加載文件時不阻塞頁面渲染。
    對於inline的script無效。
    使用這兩個屬性的腳本中不能調用document.write方法。
    有腳本的onload的事件回調。

  • 不同點
    html4.0中定義了defer,html5.0中定義了async。
    async屬性的腳本會在下載結束後立刻執行,同時會在window的load事件之前執行,所以就會出現順序被打亂的情況;defer屬性的腳本是在頁面解析完成後,按照順序執行,同時會在document的DOMContentLoaded之前執行。
    總體來說,defer和async的主要不同就是defer會保證腳本的順序,async不保證順



作者:飢人谷_Shirley
鏈接:https://www.jianshu.com/p/757f56ebe5e1
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章