1. 程式人生 > 其它 >Defer Script 和 Async Script

Defer Script 和 Async Script

Defer Script 和 Async Script

https://javascript.info/script-async-defer

使用方式

首先來看一下以下三種不同的 js 引入方式:

<!-- 一、普通的 js 引入方式 -->
<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- 二、含有 defer 屬性的 js 引入方式 -->
<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- 三、含有 async 屬性的 js 引入方式 -->
<script async src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

區別

先看一張圖

根據上圖我們大致可以理解 ScriptDefer ScriptAsync Script 三者的區別:

  1. Script 根據在 HTML 中的宣告順序依次下載並執行。一旦遇到 script 標籤則立即中斷 DOM 的解析,轉而下載和執行該 Script
  2. Defer Script 則是根據在 HTML 中的宣告順序在後臺進行下載,直至 DOM 解析完畢後(DOMContentLoaded 執行之前)再執行該 script。遇到 defer script 不會中斷 DOM 的解析。
  3. Async Script 和 Defer Script 有一個共同點:並行下載,它們都不會阻塞頁面。但是不同於 Defer Script 的是:Async Script 在下載完畢後會中斷 DOM 的解析(除非此時 DOM 已經渲染完畢),因此它有可能在 DOMContentLoaded 之前執行, 也有可能在 DOMContentLoaded 之後執行,這取決於 Async Script 的下載和 DOM 解析的過程誰先完成。(Async Script 可以用作網站訪問分析,因此它們不依賴於其他任何的 script 和 DOM 元素,同時其他內容也不依賴於它們)
  4. Defer Script 是宣告優先,它們根據其在 HTML 中宣告的順序有序執行。而 Async Script 則是載入優先,誰先下載完畢誰就先去執行。

補充內容

  1. DOM 解析完畢並不意味著可以立即在瀏覽器看到展示的內容,而是可以通過 document 操作頁面元素而已
  2. Defer Script 和 Async Script 只對含有 src 屬性的外部指令碼生效
  3. 如果在一個 script 上同時設定 async 和 defer 屬性,那麼 async 屬性則具有比 defer 更高的優先順序,僅當瀏覽不支援 Async Script 但支援 Defer Script 時 defer 屬性才生效,否則兩者都不生效。
  4. 如果你使用的是 Defer Script 或 Async Script,那麼使用者將在 指令碼載入完成之前 先看到頁面。在這種情況下,某些圖形元件可能尚未初始化完成。因此,請記得新增一個 "正在載入" 的提示,並禁用那些尚不可用的按鈕。以讓使用者可以清楚地看到,他現在可以在頁面上做什麼,以及還有什麼是正在準備中的。

Dynamic Script

我們稱下面這類 script 為 Dynamic Script

const script = document.createElement('script');
script.src = 'test.js';
document.body.appendChild(script);
console.log(script.async);  // true
console.log(script.defer);  // false

通過控制檯的列印結果可知:Dynamic Script 等同於 Async Script,當然我們可以通過在其載入到頁面之前修改相應的屬性值來改變其執行順序。