跳至內容

效能

儘管 Vite 預設速度很快,但隨著專案需求的增長,可能會出現效能問題。本指南旨在協助您識別並修正常見的效能問題,例如

  • 伺服器啟動緩慢
  • 頁面載入緩慢
  • 建置緩慢

檢查您的瀏覽器設定

某些瀏覽器擴充功能可能會干擾請求,並減慢大型應用程式的啟動和重新載入時間,尤其是在使用瀏覽器開發人員工具時。我們建議在這些情況下,建立一個沒有擴充功能的僅限開發用的設定檔,或切換到無痕模式,同時使用 Vite 的開發伺服器。無痕模式也應該比沒有擴充功能的常規設定檔更快。

Vite 開發伺服器會對預先綁定的依賴項進行硬快取,並為原始碼實作快速的 304 回應。在開啟瀏覽器開發人員工具時停用快取可能會對啟動和整頁重新載入時間產生重大影響。請檢查您在使用 Vite 伺服器時是否未啟用「停用快取」。

稽核已設定的 Vite 外掛

Vite 的內部和官方外掛都經過最佳化,以盡可能減少工作量,同時提供與更廣泛生態系統的相容性。例如,程式碼轉換在開發期間使用正規表示式,但在建置時進行完整的解析,以確保正確性。

然而,社群外掛的效能不在 Vite 的控制範圍內,這可能會影響開發人員體驗。以下是使用其他 Vite 外掛時可以注意的一些事項

  1. 僅在某些情況下使用的大型依賴項應動態匯入,以減少 Node.js 的啟動時間。範例重構:vite-plugin-react#212vite-plugin-pwa#224

  2. buildStartconfigconfigResolved 鉤子不應執行長時間和廣泛的操作。這些鉤子會在開發伺服器啟動期間被等待,這會延遲您在瀏覽器中存取網站的時間。

  3. resolveIdloadtransform 鉤子可能會導致某些檔案載入速度比其他檔案慢。雖然有時是不可避免的,但仍值得檢查是否有可最佳化的區域。例如,在執行完整轉換之前,檢查 code 是否包含特定關鍵字,或 id 是否符合特定副檔名。

    轉換檔案所需的時間越長,在瀏覽器中載入網站時的請求瀑布就越顯著。

    您可以使用 vite --debug plugin-transformvite-plugin-inspect 來檢查轉換檔案所需的時間。請注意,由於非同步操作往往會提供不精確的計時,您應該將這些數字視為粗略的估計值,但它仍然應該揭示更昂貴的操作。

效能分析

您可以執行 vite --profile,訪問網站,並在您的終端機中按下 p + enter 來記錄 .cpuprofile。然後可以使用 speedscope 之類的工具來檢查分析檔並識別瓶頸。您也可以與 Vite 團隊分享分析檔,以幫助我們識別效能問題。

減少解析操作

當經常達到最差情況時,解析匯入路徑可能是一項昂貴的操作。例如,Vite 支援使用 resolve.extensions 選項「猜測」匯入路徑,該選項預設為 ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']

當您嘗試使用 import './Component' 匯入 ./Component.jsx 時,Vite 將執行以下步驟來解析它

  1. 檢查 ./Component 是否存在,否。
  2. 檢查 ./Component.mjs 是否存在,否。
  3. 檢查 ./Component.js 是否存在,否。
  4. 檢查 ./Component.mts 是否存在,否。
  5. 檢查 ./Component.ts 是否存在,否。
  6. 檢查 ./Component.jsx 是否存在,是!

如圖所示,解析匯入路徑總共需要 6 次檔案系統檢查。您擁有的隱式匯入越多,解析路徑所花費的時間就越多。

因此,通常最好明確您的匯入路徑,例如 import './Component.jsx'。您也可以縮小 resolve.extensions 的清單以減少一般檔案系統檢查,但您必須確保它也適用於 node_modules 中的檔案。

如果您是外掛作者,請確保僅在需要時呼叫 this.resolve 以減少上述檢查次數。

TypeScript

如果您正在使用 TypeScript,請在您的 tsconfig.jsoncompilerOptions 中啟用 "moduleResolution": "bundler""allowImportingTsExtensions": true,以在您的程式碼中直接使用 .ts.tsx 副檔名。

避免 Barrel 檔案

Barrel 檔案是重新匯出同一目錄中其他檔案的 API 的檔案。例如

src/utils/index.js
js
export * from './color.js'
export * from './dom.js'
export * from './slash.js'

當您僅匯入單個 API 時,例如 import { slash } from './utils',該 Barrel 檔案中的所有檔案都需要被擷取和轉換,因為它們可能包含 slash API,並且可能還包含在初始化時執行的副作用。這表示您在初始頁面載入時載入了比所需更多的檔案,從而導致頁面載入速度較慢。

如果可能,您應該避免 Barrel 檔案並直接匯入個別的 API,例如 import { slash } from './utils/slash.js'。您可以閱讀 issue #8237 以取得更多資訊。

預熱常用檔案

Vite 開發伺服器僅轉換瀏覽器請求的檔案,這使其能夠快速啟動並僅對使用的檔案應用轉換。如果預期某些檔案會在短期內被請求,它也可以預先轉換檔案。但是,如果某些檔案的轉換時間比其他檔案長,仍然可能會發生請求瀑布。例如

假設一個匯入圖表,其中左側的檔案匯入右側的檔案

main.js -> BigComponent.vue -> big-utils.js -> large-data.json

只有在轉換檔案後才能知道匯入關係。如果 BigComponent.vue 需要一些時間來轉換,則 big-utils.js 必須等待輪到它,依此類推。即使內建了預先轉換,這也會導致內部瀑布。

Vite 允許您使用 server.warmup 選項來預熱您知道經常使用的檔案,例如 big-utils.js。這樣,big-utils.js 將會準備好並快取,以便在請求時立即提供。

您可以透過執行 vite --debug transform 並檢查日誌來尋找經常使用的檔案

bash
vite:transform 28.72ms /@vite/client +1ms
vite:transform 62.95ms /src/components/BigComponent.vue +1ms
vite:transform 102.54ms /src/utils/big-utils.js +1ms
vite.config.js
js
export default defineConfig({
  server: {
    warmup: {
      clientFiles: [
        './src/components/BigComponent.vue',
        './src/utils/big-utils.js',
      ],
    },
  },
})

請注意,您應該僅預熱經常使用的檔案,以免在啟動時使 Vite 開發伺服器過載。請查看 server.warmup 選項以取得更多資訊。

使用 --openserver.open 也會提供效能提升,因為 Vite 會自動預熱您的應用程式的進入點或提供的 URL 以開啟。

使用更少或原生工具

在程式碼庫不斷增長的情況下,保持 Vite 快速的關鍵是減少原始檔案 (JS/TS/CSS) 的工作量。

減少工作量的範例

  • 盡可能使用 CSS 而不是 Sass/Less/Stylus (巢狀可以由 PostCSS 處理)
  • 不要將 SVG 轉換為 UI 框架元件 (React、Vue 等)。而是將它們匯入為字串或 URL。
  • 當使用 @vitejs/plugin-react 時,避免設定 Babel 選項,以便它在建置期間跳過轉換 (僅會使用 esbuild)。

使用原生工具的範例

使用原生工具通常會導致較大的安裝檔案大小,因此在開始新的 Vite 專案時,它不是預設選項。但對於較大型的應用程式來說,這可能值得付出代價。

在 MIT 許可下發布。(ccee3d7c)