使用 webpack 設定效能預算

Milica Mihajlija
Milica Mihajlija

Webpack 會將所有匯入的檔案合併,並將其封裝成一個或多個輸出檔案,稱為套件。套件很方便,但隨著應用程式成長,套件也會增加。您需要監控套件大小,確保套件不會變得過大,影響應用程式載入時間。Webpack 支援根據素材資源大小設定效能預算,並可持續監控套件大小。

以下是應用程式計算新年到來前的剩餘天數,讓您瞭解這項功能的運作方式。這個應用程式是使用 Reactmoment.js 建構而成。(就像現實世界中的應用程式,越來越仰賴架構和程式庫。😉?)

應用程式會計算距離元旦還有幾天

測量

本程式碼研究室已包含與 webpack 捆綁的應用程式。

  1. 按一下「Remix to Edit」,即可編輯專案。
  2. 按一下「Terminal」 (注意:如果沒有顯示「Terminal」按鈕,您可能需要使用「Fullscreen」選項)。
  3. 如要取得以顏色編碼的素材資源清單及其大小,請在控制台中輸入 webpack
webpack

主套件大於 244 KiB (250 KB),因此會以黃色醒目顯示。

Webpack 輸出內容顯示套件大小為 323 KiB
Webpack 警告您有關龐大 JS 套件的資訊 ⚠️

這些警告預設會在正式版模式中啟用,且預設閾值為 244 KiB 未壓縮,適用於素材資源和進入點 (在網頁初次載入時使用的所有素材資源組合)。

Webpack 警告指出素材資源超出建議的大小上限
Webpack 警告您 JS 套件過大 ⚠️

Webpack 不僅會發出警告,還會提供如何縮減套件大小的建議。如要進一步瞭解建議的技術,請參閱「網頁基礎知識」。

Webpack 效能最佳化建議
Webpack 效能最佳化建議 💁?

設定自訂成效預算

適當的效能預算取決於專案性質。建議您自行研究黃金法則:提供壓縮/精簡的關鍵路徑資源,大小不超過 170 KB。

在這個簡單的示範中,我們會設定更保守的預算,將預算設為 100 KB (97.7 KiB)。在 webpack.config.js 中新增以下內容:

module.exports = {
  //...
  performance: {
    maxAssetSize: 100000,
    maxEntrypointSize: 100000,
    hints: "warning"
  }
};

新的成效預算以 bytes 為單位:

  • 個別素材資源 (maxAssetSize) 為 100000 位元組
  • 進入點的 100000 個位元組 (maxEntrypointSize)

在這種情況下,只有一個套件可做為進入點。

hints 的可能值如下:

  1. warning (預設):顯示黃色警告訊息,但建構作業會通過。建議您在開發環境中使用此選項。
  2. error:顯示紅色錯誤訊息,但建構作業仍會通過。建議將這項設定用於正式版版本。
  3. false:不會顯示警告或錯誤訊息。
以紅色字型顯示的 Webpack 效能錯誤
Webpack 效能提示「error」 🚨?

最佳化

效能預算的目的是在效能問題變得難以修正前,先向您發出警告。建構應用程式的方式不只一種,有些技巧可加快載入時間。(許多最佳化技巧都收錄在「最佳化 JavaScript」一文中。🤓?)

架構和程式庫可讓開發人員的工作更輕鬆,但使用者並不在意應用程式如何建構,只在乎應用程式是否實用且速度快。如果您發現自己超出成效預算,就該考慮可行的最佳化方式了。

在現實世界中,大型用戶端架構通常難以替換,因此請務必明智使用。只要稍微研究一下,您通常就能找到熱門程式庫的較小替代方案,而且功能也一樣強大 (date-fnsmoment.js 的絕佳替代方案)。有時,如果架構或程式庫會對效能造成重大影響,不使用這些架構或程式庫會更合理。

移除未使用的程式碼,是針對包含大型第三方程式庫的應用程式進行最佳化的好方法。「移除未使用的程式碼指南」詳細說明這個程序,以下是快速方法,可在不使用 moment.js 的情況下重新編寫倒數計時器程式碼。

app/components/Countdown.jsx 中移除:

const today = moment();
const yearEnd = moment().endOf('year');
const daysLeft = yearEnd.diff(today, 'days');

並刪除這一行:

const moment = require('moment');

這需要一點數學知識,但您可以使用一般 JavaScript 實作相同的倒數功能:

const today = new Date();
const year = today.getFullYear();
const yearEnd = new Date(year,11,31); //months are zero indexed in JS
const timeDiff = Math.abs(yearEnd.getTime() - today.getTime());
const daysLeft = Math.ceil(timeDiff / (1000 * 3600 * 24));

現在請從 package.json 中移除 moment.js,然後再次在控制台中執行 webpack,以建構最佳化套件。

好了!您已減少 223 KiB (230KB),應用程式已符合預算。🎉?

經過最佳化後,Webpack 套件大小輸出值為 97.7 KiB

監控

在 webpack 中設定效能預算只需要幾行程式碼,如果您不小心新增了大型依附元件,系統會發出警告。俗話說「眼不見,心不煩」,但 webpack 可確保您隨時瞭解成效影響。