定義
defer:此布林屬性被設定為向瀏覽器指示指令碼在文件被解析後執行。
async:設定此布林屬性,以指示瀏覽器如果可能的話,應非同步執行指令碼。複製程式碼
對於defer,我們可以認為是將外鏈的js放在了頁面底部。js的載入不會阻塞頁面的渲染和資源的載入。不過defer會按照原本的js的順序執行,所以如果前後有依賴關係的js可以放心使用。
對於async,這個是html5中新增的屬性,它的作用是能夠非同步的載入和執行指令碼,不因為載入指令碼而阻塞頁面的載入。一旦載入到就會立刻執行在有async的情況下,js一旦下載好了就會執行,所以很有可能不是按照原本的順序來執行的。如果js前後有依賴性,用async,就很有可能出錯。
區別
相同點:
- 載入檔案時不阻塞頁面渲染
- 對於inline的script(內聯指令碼)無效
- 使用這兩個屬性的指令碼中不能呼叫document.write方法
- 有指令碼的onload的事件回撥
不同點:
- html的版本html4.0中定義了defer;html5.0中定義了async
- 瀏覽器相容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
async attribute | (Supported) | 3.6 (1.9.2) | 10 | — | (Supported) |
defer attribute | (Supported) | 3.5 (1.9.1) | 4 | — | (Supported) |
- 執行時刻
每一個async屬性的指令碼都在它下載結束之後立刻執行,同時會在window的load事件之前執行。所以就有可能出現指令碼執行順序被打亂的情況;每一個defer屬性的指令碼都是在頁面解析完畢之後,按照原本的順序執行,同時會在document的DOMContentLoaded之前執行。
結語
簡單的來說,使用這兩個屬性會有三種可能的情況
- 如果async為true,那麼指令碼在下載完成後非同步執行。
- 如果async為false,defer為true,那麼指令碼會在頁面解析完畢之後執行。
- 如果async和defer都為false,那麼指令碼會在頁面解析中,停止頁面解析,立刻下載並且執行。
最後給一點個人的建議,無論使用defer還是async屬性,都需要首先將頁面中的js檔案進行整理,哪些檔案之間有依賴性,哪些檔案可以延遲載入等等,做好js程式碼的合併和拆分,然後再根據頁面需要使用這兩個屬性。