Vite 專案效能最佳化實戰指南
Vite 的開發體驗真的很爽快,但實際專案跑起來還是有不少可以調校的地方。這篇文章整理了我在開發和生產環境中優化 Vite 專案的一些實用技巧。
開發環境最佳化
1. 依賴預建構(Dependency Pre-Bundling)
Vite 會自動預建構依賴,但我們可以透過配置加速這個過程:
javascript
// vite.config.js
export default {
optimizeDeps: {
// 明確指定需要預建構的依賴
include: [
'vue',
'vue-router',
'pinia',
'axios',
// 深層依賴也可以指定
'lodash-es'
],
// 排除不需要預建構的依賴
exclude: ['@vueuse/core']
}
}為什麼要這樣做?
- 減少首次啟動時的依賴掃描時間
- 避免某些套件在運行時被重複轉換
- 特別是對於有大量依賴的專案,可以明顯提升啟動速度
2. 模組熱更新(HMR)最佳化
合理的元件拆分可以提升 HMR 的效率:
javascript
// ❌ 不好的做法:單一巨大檔案
// App.vue 包含所有邏輯、樣式、子元件
// ✅ 好的做法:拆分元件和樣式
// App.vue
import Header from './components/Header.vue'
import Content from './components/Content.vue'
import Footer from './components/Footer.vue'技巧:
- 將大型元件拆分成更小的單元
- 樣式檔案獨立管理,避免 CSS 和 JS 綁定
- 使用
<script setup>語法,Vite 對其有更好的 HMR 支援
3. 路徑別名配置
設定路徑別名不僅提升開發體驗,也能加速模組解析:
js
// vite.config.js
import { fileURLToPath, URL } from 'node:url'
export default {
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@components': fileURLToPath(new URL('./src/components', import.meta.url)),
'@utils': fileURLToPath(new URL('./src/utils', import.meta.url))
}
}
}生產環境最佳化
1. Code Splitting 策略
路由層級的分割
javascript
// router/index.js
const routes = [
{
path: '/dashboard',
// 使用動態 import
component: () => import('@/views/Dashboard.vue')
},
{
path: '/settings',
component: () => import('@/views/Settings.vue')
}
]元件層級的分割
vue
<script setup>
import { defineAsyncComponent } from 'vue'
// 大型元件使用 lazy loading
const HeavyChart = defineAsyncComponent(() =>
import('@/components/HeavyChart.vue')
)
</script>手動分割 chunk
javascript
// vite.config.js
export default {
build: {
rollupOptions: {
output: {
manualChunks: {
// 將 Vue 生態系分離出來
'vue-vendor': ['vue', 'vue-router', 'pinia'],
// UI 框架獨立打包
'ui-vendor': ['element-plus'],
// 工具函式庫
'utils': ['lodash-es', 'dayjs']
}
}
}
}
}為什麼要分割 chunk?
- 提升瀏覽器快取效率
- 第三方庫變動頻率低,分離後可以長期快取
- 減少首次載入的 bundle 大小
2. 壓縮與最佳化
Gzip/Brotli 壓縮
javascript
// vite.config.js
import viteCompression from 'vite-plugin-compression'
export default {
plugins: [
viteCompression({
algorithm: 'gzip',
ext: '.gz'
}),
viteCompression({
algorithm: 'brotliCompress',
ext: '.br'
})
]
}CSS 最佳化
javascript
export default {
css: {
// 生產環境移除未使用的 CSS
postcss: {
plugins: [
require('autoprefixer'),
require('cssnano')({
preset: 'default'
})
]
}
}
}3. 圖片最佳化
使用 Vite 插件處理圖片:
javascript
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'
export default {
plugins: [
ViteImageOptimizer({
png: {
quality: 80
},
jpeg: {
quality: 80
},
webp: {
quality: 80
}
})
]
}實務建議:
vue
<template>
<!-- 使用現代圖片格式 -->
<picture>
<source srcset="/images/hero.webp" type="image/webp">
<source srcset="/images/hero.jpg" type="image/jpeg">
<img src="/images/hero.jpg" alt="Hero image">
</picture>
</template>4. Tree Shaking 最佳化
確保套件支援 tree shaking:
javascript
// ❌ 不利於 tree shaking
import _ from 'lodash'
// ✅ 使用 ES modules 版本
import { debounce, throttle } from 'lodash-es'
// ✅ 直接引用需要的函式
import debounce from 'lodash-es/debounce'Build 效能最佳化
1. 使用 esbuild 或 SWC
javascript
export default {
build: {
// 使用 esbuild 壓縮(預設)
minify: 'esbuild',
// 或使用 terser 獲得更好的壓縮率
// minify: 'terser',
}
}2. 平行處理
javascript
export default {
build: {
// 啟用多執行緒建構
terserOptions: {
compress: {
parallel: true
}
}
}
}3. Source Map 策略
javascript
export default {
build: {
// 開發環境使用完整 source map
sourcemap: process.env.NODE_ENV === 'development' ? true : false,
// 生產環境可以選擇隱藏或使用輕量版
// sourcemap: 'hidden'
}
}效能監控
使用 Vite Bundle Analyzer
javascript
import { visualizer } from 'rollup-plugin-visualizer'
export default {
plugins: [
visualizer({
open: true,
gzipSize: true,
brotliSize: true
})
]
}這會生成一個互動式的 bundle 分析圖,幫助你找出可以最佳化的部分。
實際案例:專案最佳化前後對比
在一個中型專案中,應用上述技巧後的效果:
開發環境:
- 啟動時間:從 3.2s 降至 1.8s(44% 提升)
- HMR 更新:從 800ms 降至 200ms
生產環境:
- 首次載入時間:從 2.1s 降至 1.2s
- Bundle 大小:從 850KB 降至 420KB(使用 gzip)
總結
優化 Vite 專案主要抓住幾個重點:
- 開發環境:專注於啟動速度和 HMR 效率
- 生產環境:著重於 bundle 大小和載入效能
- 持續監控:使用分析工具找出瓶頸
效能優化是個持續的過程,要看專案實際狀況來調整。記住一個原則:不要過早優化,先用工具找出真正的瓶頸在哪裡,再針對性地解決。
我的建議是養成定期檢查 bundle 分析的習慣,這樣才能確保效能不會隨著專案成長而越來越糟。