为什么我们用了 Vite 还是构建慢?——真正的优化在这几步

Vite 凭借其基于原生 ESM 的开发体验和极速冷启动,被誉为"现代前端构建的终极解决方案"。然而,许多开发者在将老项目迁移到 Vite 或新项目上马后,仍会面临以下现实:

  • 冷启动是快了,但热更新开始卡顿
  • 构建产物还是几十秒甚至上百秒
  • vite build 一跑,CPU 风扇飞起,内存飙升

这不禁让人怀疑:Vite 真的快吗?我是不是哪里搞错了?

答案是:Vite 本身没错,但你可能忽略了 "构建速度的决定性因素" 并不只是工具,而是你整个工程的结构与使用方式。


第一步:认清 Vite 的本质------开发快 ≠ 构建快

Vite 的核心价值之一是:

开发时基于原生 ESM 模块按需加载,只构建你当前用到的模块。

所以你在开发时能享受到:

  • 秒级冷启动
  • 快速热更新(HMR)

但是一旦 vite build,它会切换到底层的 Rollup 作为打包器。这时候:

  • 所有依赖和模块都会被打包(并非按需加载)
  • 你项目里隐藏的复杂性就无所遁形了

如果你项目构建慢,问题通常出在这几个地方 👇


第二步:从源码开始拆解瓶颈

1. 依赖体积巨大,tree-shaking 无效

常见现象:

  • 引入了 lodash,但只用了一个 cloneDeep,结果全库都进来了
  • 三方组件库未按需引入
  • import 了整个 moment/antd/dayjs/chart.js 等大块头

建议:

  • 替换为按需引入版本(例如 lodash-es、dayjs)
  • 配置 vite-plugin-imp、unplugin-vue-components 等插件实现自动按需加载
  • 使用 esbuild 插件提前预构建大型依赖

2. 依赖过多,预构建时间拉长

Vite 会在第一次启动时对第三方依赖进行 预构建,但如果:

  • node_modules 太大
  • dependencies 和 devDependencies 没分清
  • 重复安装多个版本的库

则预构建变成噩梦。

建议:

  • 使用 optimizeDeps.exclude 排除不必要的模块
  • 确保依赖升级一致,避免 lodash@3 和 lodash@4 共存
  • 使用 pnpm 或 yarn workspace 做 hoist 减少重复依赖

3. 大量动态导入 / 动态路由

javascript 复制代码
const page = import(`./pages/${name}.vue`)

这类动态导入虽然在开发阶段无感,但在打包时会造成:

  • 无法静态分析,打包粒度变粗
  • chunk 切割不理想

建议:

  • 避免使用过多复杂路径的 import()
  • 显式声明 chunk 名称:
javascript 复制代码
const page = import(/* webpackChunkName: "page-[request]" */ `./pages/${name}.vue`)
  • 使用插件 vite-plugin-pages 提前生成路由,提升打包可控性

4. 打包时文件过多或模块层级过深

Vite 最怕你这样:

  • 单页项目动辄几千个 .vue 文件
  • 组件层级 6 层嵌套,导入链冗长

这样会造成:

  • Rollup 构建图构造时间大大增加
  • chunk 分析变慢

建议:

  • 控制模块划分粒度
  • 重构庞大的组件结构
  • 使用 vite-plugin-inspect 或 why-so-slow 工具分析依赖链路

第三步:构建优化技巧全集

✅ 开启 Rollup 缓存(生产构建)

php 复制代码
export default defineConfig({
  build: {
    cacheDir: 'node_modules/.vite_cache',
  },
})

✅ 使用 esbuild 插件压缩而不是 Terser

css 复制代码
build: {
  minify: 'esbuild', // 默认为 terser,esbuild 更快
}

✅ 压缩大型依赖提前剥离(optimizeDeps + manualChunks)

css 复制代码
optimizeDeps: {
  include: ['axios', 'lodash-es'],
}
css 复制代码
rollupOptions: {
  output: {
    manualChunks: {
      vendor: ['vue', 'vue-router'],
    },
  },
}

✅ 设置 SSR-friendly 构建配置

如果你的项目未来有 Nuxt / SSR 的诉求:

css 复制代码
ssr: {
  noExternal: ['your-lib'], // 避免库在服务端打包出错
}

第四步:缓存、预构建、硬盘读写也重要

  • .vite 缓存目录删除后构建速度会变慢一次
  • node_modules 删除后会触发重新 optimizeDeps
  • 高并发文件读取(尤其在 HDD 硬盘上)会导致构建性能极差

建议:

  • 使用 SSD 做本地开发盘
  • 保留 .vite 缓存目录
  • 在 CI/CD 中加缓存提升构建速度

Vite 是好工具,但别用错姿势

Vite 真的快,但也真的依赖你的项目结构合理性。如果你像用 Webpack 一样对待 Vite,把所有依赖全部一锅端地丢进来,还觉得构建变慢了,那问题不在工具,而在使用方式。

所以,如果你真的想优化构建速度:

  • 别急着 blame Vite
  • 先看看自己是不是喂了它太多"垃圾"代码
相关推荐
夏幻灵3 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记3 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习4 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194054 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风5 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn6 小时前
框架性能优化
前端
回眸&啤酒鸭8 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013848 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员8 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子8 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端