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

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

傳送大型 JavaScript 酬載會大幅影響網站速度。請在應用程式的第一個頁面載入後,立即將所有 JavaScript 傳送給使用者。請改為將套裝組合分割為多個部分,只在開頭傳送必要項目。

為何程式碼分割有益?

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

如果採用網站體驗核心指標,減少啟動時下載的 JavaScript 酬載,可以提升與下一個繪製 (INP) 互動 (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 的熱門架構都提供抽象概念,讓延遲載入功能更容易使用,不必自行深入研究設定。