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

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

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

為何分割程式碼有助於提升效能?

程式碼分割是一種技巧,可盡量縮短啟動時間。如果在啟動時傳送的 JavaScript 較少,我們就能在這個關鍵期間盡量減少主執行緒的工作,讓應用程式更快完成互動

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

視網站架構而定 (尤其是網站大量仰賴用戶端轉譯),縮減負責轉譯標記的 JavaScript 酬載大小,可能有助於縮短最大內容繪製 (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 的熱門架構都提供抽象概念,讓延遲載入功能更容易使用,不必自行深入研究設定。