第一次用 Vite 替代 Webpack 時,確實被驚豔到了——之前項目啓動要等 30 秒,換成 Vite 後秒開,熱更新也幾乎沒有延遲。但用久了發現,隨着項目變大,Vite 也會變慢:啓動時控制枱刷一堆依賴,熱更新偶爾卡頓,生產構建時間逐漸變長。其實只要掌握一些優化技巧,就能讓 Vite 始終保持“飛一般的感覺”。

一、依賴預構建:減少啓動時間

Vite 啓動快的核心是“按需編譯”,但 node_modules 裏的第三方依賴(如 React、Vue)大多是 CommonJS 格式,需要先轉成 ESM 才能被瀏覽器直接使用。Vite 會自動做這件事,也就是“依賴預構建”,但默認配置在大項目裏可能拖慢啓動速度。

1. 控制預構建範圍

默認情況下,Vite 會掃描入口文件和依賴中的 import 語句,自動找出需要預構建的依賴。但有些依賴可能被誤納入,可通過 optimizeDeps.exclude 排除:

// vite.config.js
export default {
  optimizeDeps: {
    // 排除不需要預構建的依賴(如已是 ESM 格式的庫)
    exclude: ['lodash-es'], // lodash-es 本身就是 ESM,無需預構建
    // 強制預構建某些依賴(解決偶爾的依賴解析問題)
    include: ['axios/dist/browser/axios.cjs']
  }
}

2. 緩存預構建結果

Vite 會把預構建結果存在 node_modules/.vite 目錄,下次啓動直接複用。但如果依賴有更新,需要手動刪除緩存。可在 package.json 加個腳本快速清理:

"scripts": {
  "vite:clean": "rm -rf node_modules/.vite"
}

遇到啓動報錯或依賴更新後,執行 npm run vite:clean 再啓動,比刪 node_modules 高效多了。

二、熱更新優化:實時反饋不卡頓

熱更新(HMR)是 Vite 的強項,但組件嵌套深、文件體積大時,可能出現更新延遲。

1. 縮小 HMR 範圍

Vite 默認會監聽所有源碼文件,但有些目錄(如 distpublic)不需要監聽。通過 server.watch 配置縮小監聽範圍:

// vite.config.js
export default {
  server: {
    watch: {
      // 排除不需要監聽的目錄
      ignored: ['**/node_modules/**', '**/dist/**', '**/.git/**']
    }
  }
}

2. 組件級 HMR 優化

Vue 和 React 項目可通過框架特性進一步優化 HMR:

  • Vue 項目:確保組件使用 <script setup>defineComponent,Vite 對這兩種寫法的 HMR 支持更高效。避免在根組件寫過多邏輯,拆分後熱更新更快。
  • React 項目:安裝 @vitejs/plugin-react 並啓用 fastRefresh(默認開啓),它能保留組件狀態的同時更新代碼:
// vite.config.js
import react from '@vitejs/plugin-react';

export default {
  plugins: [
    react({
      fastRefresh: true, // 啓用快速刷新
      // 排除不需要 HMR 的文件
      exclude: /node_modules/,
      include: /\.(js|jsx|ts|tsx)$/
    })
  ]
}

3. 禁用不必要的插件

開發環境下,某些插件(如代碼壓縮、分析插件)只會拖慢速度,可只在生產環境啓用:

// vite.config.js
import { defineConfig } from 'vite';
import compress from 'vite-plugin-compression';
import analyze from 'rollup-plugin-visualizer';

export default defineConfig(({ mode }) => {
  const plugins = [];
  
  // 只在生產環境啓用壓縮和分析插件
  if (mode === 'production') {
    plugins.push(compress());
    plugins.push(analyze());
  }
  
  return { plugins };
});

三、生產構建優化:減小體積+加速打包

Vite 生產環境用 Rollup 打包,默認配置已經不錯,但還有優化空間。

1. 代碼分割更合理

通過 build.rollupOptions 自定義代碼分割策略,避免大文件打包:

// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        // 拆包:把 node_modules 單獨打包
        manualChunks: {
          vendor: ['vue', 'vue-router'], // 框架相關
          utils: ['lodash', 'axios'] // 工具庫相關
        }
      }
    }
  }
}

拆包後,用户第二次訪問時,未變更的 vendor 包可直接用緩存,減少加載時間。

2. 圖片和資源優化

Vite 內置了圖片處理,但可進一步壓縮資源:

// vite.config.js
import { defineConfig } from 'vite';
import imagemin from 'vite-plugin-imagemin';

export default defineConfig({
  plugins: [
    // 生產環境壓縮圖片
    imagemin({
      gifsicle: { optimizationLevel: 3 }, // GIF 壓縮
      optipng: { optimizationLevel: 2 }, // PNG 壓縮
      mozjpeg: { quality: 80 }, // JPEG 壓縮
      svgo: true // SVG 壓縮
    })
  ],
  build: {
    // 小於 4KB 的圖片轉 base64,減少請求
    assetsInlineLimit: 4 * 1024,
    // 啓用 CSS 代碼分割(默認關閉)
    cssCodeSplit: true
  }
});

安裝插件:npm install vite-plugin-imagemin --save-dev(國內用户可能需要配置鏡像)。

3. 多線程打包

rollup-plugin-multi-entry 配合 esbuild 多線程加速:

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  esbuild: {
    // 啓用多線程編譯
    workers: process.env.NODE_ENV === 'production' ? 'max' : false
  },
  build: {
    // 使用 esbuild 壓縮(比 terser 快)
    minify: 'esbuild',
    // 關閉部分不必要的檢查
    reportCompressedSize: false
  }
});

esbuild 是 Go 寫的,壓縮速度比 JavaScript 寫的 terser 快 10-100 倍,生產環境強烈推薦。

四、網絡請求優化:本地開發更流暢

1. 配置代理解決跨域

開發環境調用 API 時,跨域請求會導致額外的 OPTIONS 預檢請求,影響速度。配置代理直接規避跨域:

// vite.config.js
export default {
  server: {
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        // 去掉路徑中的 /api 前綴
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
}

代理後請求 http://localhost:5173/api/user 會被轉發到 https://api.example.com/user,沒有跨域問題。

2. 啓用 HTTP/2

HTTP/2 支持多路複用,比 HTTP/1.1 加載資源更快,Vite 可一鍵開啓:

// vite.config.js
export default {
  server: {
    https: true, // 需要 HTTPS 才能啓用 HTTP/2
    http2: true
  }
}

開發環境用 https + http2,尤其在加載大量圖片和 JS 文件時,速度提升明顯。

五、避坑指南

  1. 依賴版本衝突:Vite 對某些舊版本依賴兼容性不好,比如 vue@2.6.x 需配合 @vitejs/plugin-vue2,別直接用默認插件。
  2. 過大的單文件:單個組件超過 1000 行代碼時,熱更新會變慢,建議拆分成小組件。
  3. 過度配置:別盲目加插件,每個插件都會增加構建時間。比如 vite-plugin-checker(類型檢查)在開發時可按需開啓,不必默認啓動。
  4. 緩存問題:生產構建後如果遇到資源加載錯誤,可能是緩存導致的。在 index.html 中給資源加哈希:
<!-- 自動生成的 script 標籤會帶哈希,如 app.8f3d.js -->
<script type="module" src="/assets/app.8f3d.js"></script>

Vite 默認會處理哈希,確保每次構建後文件名不同,避免緩存問題。

總結

Vite 的提速不是“一勞永逸”的,隨着項目增長需要針對性優化:開發環境重點優化依賴預構建和熱更新範圍,生產環境側重代碼分割和資源壓縮,網絡層面通過代理和 HTTP/2 減少請求開銷。

實際優化時,建議先用 vite --debug 查看啓動和構建的耗時細節,找到瓶頸再動手。大多數情況下,簡單調整配置就能獲得明顯提升——畢竟 Vite 的設計初衷就是“快”,我們要做的只是別讓不合理的配置拖慢它。