Vite配置实战:从零搭建高效前端开发环境
优化前:卡得不行
上周重构一个中后台项目,用的是 Vite 4 + Vue 3。本地开发跑起来还行,但一部署到测试环境,首页加载直接卡成PPT——首屏白屏5秒多,用户反馈“是不是挂了”。我点开控制台一看,bundle 包快 8MB,光 vendor.js 就占了 6MB,而且还有十几个动态 import 的 chunk,瀑布流拉得老长。最离谱的是,每次改一行代码,HMR 热更新要等 3 秒,开发体验差到想砸键盘。
找到瓶颈了!
先别急着改配置,得先搞清楚问题出在哪。我用了两个工具:
- Bundle Analyzer:装个
rollup-plugin-visualizer,跑 build 时生成依赖图谱,一眼看出 lodash、moment、echarts 全被打包进 vendor,其实只用了几个函数。 - Chrome DevTools Performance 面板:录一次加载,发现主线程被大量 script evaluation 占满,尤其是解析大 JS 文件那块,CPU 直接飙到 100%。
结论很明确:首屏资源太大,且没做合理拆分。Vite 虽然快,但默认配置对大型项目不够友好,尤其当项目里塞了各种重型库的时候。
核心优化:拆包 + 预加载 + 缓存策略
折腾了两天,试了几种方案,最后这套组合拳效果最好。
1. 手动拆分 vendor,别让 Vite 自作主张
Vite 默认会把 node_modules 里所有东西打包进 vendor,但像 echarts、xlsx 这种大库,其实只在特定页面用。我手动把它们拆出来,按需加载。
优化前的配置(啥都没配,全靠默认):
// vite.config.js
export default defineConfig({
plugins: [vue()],
})
优化后,用 build.rollupOptions.output.manualChunks 精细控制:
// vite.config.js
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('echarts')) {
return 'echarts';
}
if (id.includes('xlsx')) {
return 'xlsx';
}
if (id.includes('lodash')) {
return 'lodash';
}
// 其他公共库可继续拆
return 'vendor';
}
}
}
}
}
})
这样 build 出来,echarts.js、xlsx.js 都是独立 chunk,只有进到报表页才加载,首页体积立马减了 2MB。
2. 预加载关键资源,别等用户点击才加载
拆完包后,虽然首屏小了,但切换到报表页时,echarts 加载又卡一下。这时候用 <link rel="prefetch"> 或 preload 提前加载。
但注意:prefetch 是空闲时加载,preload 是立即加载,别乱用。我只对首屏之后**极大概率会访问**的页面做 preload。
在入口 HTML 里加:
<!-- index.html -->
<link rel="preload" as="script" href="/assets/echarts-xxxx.js" />
或者用动态 import + webpackPrefetch 注释(Vite 也支持):
// 在路由文件中
const ReportPage = () => import(/* webpackPreload: true */ '@/views/Report.vue')
实测报表页打开速度从 1.2s 降到 300ms,因为 JS 已经在后台预加载好了。
3. 启用持久缓存,别让用户重复下载
之前每次发版,所有 JS 文件名不变,浏览器缓存失效,用户得重新下 8MB。Vite 默认会加 hash,但得确保服务器正确配置缓存头。
build 后的文件名类似 index.abc123.js,只要内容不变,hash 就不变。所以 Nginx 配置加上:
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
这样用户第二次访问,所有静态资源直接走 disk cache,加载时间从 5s+ 降到 800ms 以内(主要是 API 请求时间)。
其他小优化(带过)
- 关闭 sourcemap:生产环境别开
build.sourcemap = false,能省几百 KB。 - 压缩图片:用
vite-plugin-imagemin自动压缩,但注意别过度压缩导致失真。 - Tree-shaking 检查:确保用 ES Module 引入,比如
import { debounce } from 'lodash-es'而不是import _ from 'lodash',否则整个 lodash 都会被打包。
这里注意我踩过好几次坑:有些 UI 库(比如某 Element Plus)默认导出的是 CJS,得手动配置 resolve.alias 指向 esm 版本,否则 tree-shaking 无效。
性能数据对比
优化前后实测数据(同一台测试机,Chrome 无痕模式):
- 首屏加载时间:5.2s → 780ms(Lighthouse 评分从 42 → 89)
- 主包体积:8.1MB → 2.3MB(gzip 后)
- HMR 热更新:3.1s → 400ms(开发体验飞起)
最爽的是,现在改代码几乎秒级热更新,再也不用盯着转圈圈的 logo 发呆了。
还有点小遗憾
虽然整体流畅多了,但有个小问题没彻底解决:首次加载时,如果网络慢,loading 动画会闪一下(因为 CSS 还没加载完)。理论上可以用 inline critical CSS 解决,但项目里 CSS 量不大,优先级不高,就先放着了。毕竟优化不是追求完美,而是解决最痛的点。
以上是我这次 Vite 配置优化的实战经验,核心就是三点:拆大包、预加载、设缓存。这个方案不是最优的(比如还可以用 code splitting + route-based chunking 更精细),但胜在简单有效,改完立刻见效。有更优的实现方式欢迎评论区交流,或者你也在 Vite 里踩过类似的坑?一起聊聊。

暂无评论