文章來源 n͛i͛g͛h͛t͛i͛r͛e͛ 大佬的回答segmentfault
先來試個一句話解釋仨,當瀏覽器碰到 script 腳本的時候:瀏覽器
<script src="script.js"></script>網絡
沒有 defer 或 async,瀏覽器會當即加載並執行指定的腳本,「當即」指的是在渲染該 script 標籤之下的文檔元素以前,也就是說不等待後續載入的文檔元素,讀到就加載並執行。異步
<script async src="script.js"></script>async
有 async,加載和渲染後續文檔元素的過程將和 script.js 的加載與執行並行進行(異步)。優化
<script defer src="myscript.js"></script>spa
有 defer,加載後續文檔元素的過程將和 script.js 的加載並行進行(異步),可是 script.js 的執行要在全部元素解析完成以後,DOMContentLoaded 事件觸發以前完成。事件
而後從實用角度來講呢,首先把全部腳本都丟到 </body> 以前是最佳實踐,由於對於舊瀏覽器來講這是惟一的優化選擇,此法可保證非腳本的其餘一切元素可以以最快的速度獲得加載和解析。ip
接着,咱們來看一張圖咯:文檔
藍色線表明網絡讀取,紅色線表明執行時間,這倆都是針對腳本的;綠色線表明 HTML 解析。
此圖告訴咱們如下幾個要點:
defer 和 async 在網絡讀取(下載)這塊兒是同樣的,都是異步的(相較於 HTML 解析)它倆的差異在於腳本下載完以後什麼時候執行,顯然 defer 是最接近咱們對於應用腳本加載和執行的要求的關於 defer,此圖未盡之處在於它是按照加載順序執行腳本的,這一點要善加利用async 則是一個亂序執行的主,反正對它來講腳本的加載和執行是牢牢挨着的,因此無論你聲明的順序如何,只要它加載完了就會馬上執行仔細想一想,async 對於應用腳本的用處不大,由於它徹底不考慮依賴(哪怕是最低級的順序執行),不過它對於那些能夠不依賴任何腳本或不被任何腳本依賴的腳原本說倒是很是合適的,最典型的例子:Google Analytics