Vite项目开发期快,生产构建却慢,打包产物超过1MB,首屏白屏几秒,这是从Webpack迁移到Vite后容易踩的坑。Vite构建优化的核心两块:一是依赖预构建(esbuild加速依赖转化),二是构建分包(拆出不常变的vendor代码利用浏览器缓存)。下面按定位、优化、验证的顺序讲。
Vite构建链路的瓶颈定位方法
先量化再优化。用官方插件vite-plugin-inspect和构建耗时分析:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import inspect from 'vite-plugin-inspect'
import visualizer from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [vue(), inspect(), visualizer()],
build: {
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[hash].[ext]',
chunkFileNames: 'chunks/[name]-[hash].js'
}
}
}
})
构建后看dist目录里最大的chunk是哪个,再用npm run build — –report生成可视化依赖图,一眼看出谁占了体积。
依赖预构建配置:optimizeDeps与缓存失效
Vite首次启动时会把node_modules里的依赖预构建成ESM格式,缓存在node_modules/.vite。常见问题:新增依赖后没反应、依赖版本更新了还在用旧缓存。处理方法:
// vite.config.ts
export default defineConfig({
optimizeDeps: {
// 显式声明需要预构建的依赖,避免扫描遗漏
include: ['vue', 'vue-router', 'pinia', 'axios', 'echarts'],
// 排除不需要预构建的库
exclude: ['your-local-lib']
}
})
注意include里不要写太多,预构建的依赖越多冷启动越慢。改动package-lock后如果缓存不刷新,直接删除node_modules/.vite即可。
手动分包策略:把vendor和大模块拆成独立chunk
不拆包时,几十个依赖全部打在一个vendor.js里,改一行业务代码整个vendor缓存失效。手动分包示例:
// vite.config.ts
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('echarts') || id.includes('zrender')) {
return 'charts' // 图表库独立
}
if (id.includes('vue') || id.includes('pinia') || id.includes('vue-router')) {
return 'vue-vendor' // Vue生态独立
}
if (id.includes('axios') || id.includes('lodash-es')) {
return 'utils'
}
return 'vendor' // 其他依赖
}
}
}
}
}
同时配合路由级懒加载,把页面组件拆成按需加载的chunk。主包只保留核心逻辑,首屏只请求路由对应的chunk。
构建产物体积分析与tree-shaking校验
分包后校验浏览器缓存是否真正生效、每个chunk体积是否合理。用gzip压缩对比体积:
# 构建
npm run build
# 统计各chunk gzip后体积
find dist -name "*.js" | xargs -I {} sh -c 'echo "{}: $(gzip -c {} | wc -c) bytes"'
# 生成依赖分析报告
npm run build -- --report
检查有没有没用的库被整包引入,比如只用了lodash的某个函数却整包引入,建议换成lodash-es。echarts大包改用按需引入,树的体积能再降一半。Vite优化的核心是让浏览器缓存命中最大化:依赖chunk几乎不变、业务chunk按路由切分,这样用户每次升级只下载几十KB的业务代码,而不是重新下载整个应用。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/vite-gou-jian-you-hua-shi-zhan-yi-lai-yu-gou-jian-yu-fen/