script中defer和async的區別

Juicyangxj發表於2017-11-20

定義

  defer:此布林屬性被設定為向瀏覽器指示指令碼在文件被解析後執行。
  async:設定此布林屬性,以指示瀏覽器如果可能的話,應非同步執行指令碼。複製程式碼
  1. 對於defer,我們可以認為是將外鏈的js放在了頁面底部。js的載入不會阻塞頁面的渲染和資源的載入。不過defer會按照原本的js的順序執行,所以如果前後有依賴關係的js可以放心使用。

  2. 對於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之前執行。

結語

簡單的來說,使用這兩個屬性會有三種可能的情況

  1. 如果async為true,那麼指令碼在下載完成後非同步執行。
  2. 如果async為false,defer為true,那麼指令碼會在頁面解析完畢之後執行。
  3. 如果async和defer都為false,那麼指令碼會在頁面解析中,停止頁面解析,立刻下載並且執行。

最後給一點個人的建議,無論使用defer還是async屬性,都需要首先將頁面中的js檔案進行整理,哪些檔案之間有依賴性,哪些檔案可以延遲載入等等,做好js程式碼的合併和拆分,然後再根據頁面需要使用這兩個屬性。

相關文章