利用程式碼分割功能減少 JavaScript 酬載

沒有人喜歡等待。 如果網站載入時間超過 3 秒,超過 50% 的使用者會放棄瀏覽

傳送大型 JavaScript 酬載會大幅影響網站速度。不要在應用程式的第一個網頁載入時,就將所有 JavaScript 傳送給使用者,而是將套件分割成多個部分,只在最開始時傳送必要項目。

程式碼分割的優點

程式碼分割是一種技術,旨在縮短啟動時間。在啟動時減少傳送的 JavaScript,就能盡量減少這段重要期間的主執行緒工作,讓應用程式更快進入互動狀態

Core Web Vitals 而言,減少啟動時下載的 JavaScript 酬載,有助於縮短 Interaction to Next Paint (INP) 時間。這麼做的原因是,釋放主要執行緒後,應用程式就能減少 JavaScript 剖析、編譯和執行相關的啟動成本,進而更快回應使用者輸入內容。

視網站架構而定 (尤其是網站大量採用用戶端轉譯時),減少負責轉譯標記的 JavaScript 酬載大小,可能有助於縮短 Largest Contentful Paint (LCP) 時間。如果瀏覽器延遲探索 LCP 資源 (直到完成用戶端標記為止),或是主要執行緒太忙而無法算繪該 LCP 元素,就可能發生這種情況。這兩種情況都會延遲網頁的 LCP 時間。

評估

如果網頁執行所有 JavaScript 的時間過長,Lighthouse 就會顯示稽核失敗。

Lighthouse 稽核失敗,顯示指令碼執行時間過長。

分割 JavaScript 組合,讓使用者載入應用程式時,只傳送初始路徑所需的程式碼。這樣一來,需要剖析及編譯的指令碼數量就會減少,網頁載入速度也會更快。

webpackParcelRollup 等熱門模組整合工具可讓您使用動態匯入功能分割套件。舉例來說,請參考下列程式碼片段,瞭解表單提交時觸發的 someFunction 方法範例。

import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  // uses moduleA
}

在這裡,someFunction 會使用從特定程式庫匯入的模組。如果這個模組未在其他地方使用,可以修改程式碼區塊,改用動態匯入,只在使用者提交表單時擷取。

form.addEventListener("submit", e => {
  e.preventDefault();
  import('library.moduleA')
    .then(module => module.default) // using the default export
    .then(() => someFunction())
    .catch(handleError());
});

const someFunction = () => {
    // uses moduleA
}

構成模組的程式碼不會納入初始套件,而是延遲載入,或是在表單提交後,僅在需要時提供給使用者。如要進一步提升網頁效能,請預先載入重要區塊,優先擷取這些區塊

雖然先前的程式碼片段是簡單的範例,但在較大的應用程式中,延遲載入第三方依附元件並非常見模式。通常第三方依附元件會分割成個別的供應商套件,由於更新頻率不高,因此可以快取。您可以進一步瞭解 SplitChunksPlugin 如何協助您完成這項操作。

使用用戶端架構時,在路徑或元件層級進行拆分,是延遲載入應用程式不同部分的簡單方法。許多使用 webpack 的熱門架構都提供抽象化功能,讓延遲載入比自行深入研究設定更容易。