Vue + Vite 项目中的性能优化
Vue + Vite 项目里谈性能优化,不能只盯着一个点。面试和实战里更好的表达方式是把问题拆成三层:
- 构建性能:启动慢、HMR 慢、打包慢
- 产物性能:首屏包太大、缓存命中差、资源加载慢
- 运行时性能:渲染慢、更新慢、交互卡
这篇以 Vue 3 + Vite 5/6 常见项目 为前提,讲最常用、最能落地的一套方法。
面试速答(30 秒版 TL;DR)
- Vite 已经把“开发期构建速度”做得很好,但项目大了以后,性能瓶颈仍然会出现在:
- 依赖预构建过重
- 路由首屏包过大
- 大组件和大列表重复渲染
- 静态资源和缓存策略不合理
- 优化顺序建议:
- 先定位是开发慢、构建慢还是运行慢
- 再针对性处理依赖、拆包、异步加载、渲染边界和资源体积
- 用分析工具验证,不要靠感觉
先按三层排查:开发期、构建产物、运行时。
1. 先分类定位问题
1.1 开发期慢
常见表现:
pnpm start启动慢- 首次打开页面慢
- 热更新范围大、刷新频繁
1.2 构建产物慢
常见表现:
- 首屏 JS 包很大
- 首次加载资源多
- 缓存命中差,每次发版都全量失效
1.3 运行时慢
常见表现:
- 大列表卡
- 表单输入卡
- 路由切换卡
- 一改状态就很多组件重渲染
先分类,才知道该改哪层。
2. Vite 侧优化:开发和构建层
2.1 控制依赖体积和依赖数量
Vite 开发期依赖预构建基于 esbuild,已经很快,但如果你引入了很多重型依赖,冷启动还是会变慢。
建议:
- 尽量避免重复引入功能重叠的库
- 优先使用按需能力明确的库
- 对特别重且稳定的依赖,关注是否需要预构建配置优化
2.2 路由级懒加载
这是 Vue 项目里最划算的优化之一:
const UserPage = () => import('./pages/UserPage.vue')
这样可以把非首屏页面拆成异步 chunk,减少初始包体积。
2.3 合理拆包
生产构建阶段,重点关注:
- 大型图表库
- 富文本编辑器
- 地图库
- 组件库的重资源部分
可以结合 build.rollupOptions.output.manualChunks 做定向拆包,但原则是:
- 先看分析结果
- 再拆真正的大块依赖
不要为了“看起来专业”把包拆得非常碎,导致请求和缓存策略反而更复杂。
2.4 关闭不必要的产物开销
例如:
- 生产环境不随意开启 sourcemap
- 没必要时不要输出超多分析和调试文件
- 避免把测试、mock、开发专用逻辑带进正式包
3. Vue 侧优化:减少无效渲染
3.1 稳定 props 和组件边界
父组件一更新,不代表所有子组件都应该跟着做重活。
要点:
- 拆小组件,但别过度碎片化
- 保持 props 稳定,避免每次都传全新对象/全新函数
- 把真正频繁变的状态尽量限制在局部组件内
3.2 合理使用 computed
如果某个值是同步派生结果,就优先用 computed,不要在模板里写复杂表达式,也不要每次渲染都重复做大计算。
3.3 慎用深度 watch
deep: true 很方便,但大对象上成本可能很高。能精确监听字段,就不要对整棵对象做深度监听。
3.4 使用 v-once / v-memo
v-once:完全静态且后续不变的内容v-memo:Vue 3 里对特定子树做条件记忆,减少重复 patch
这类优化适合:
- 大片静态说明区
- 复杂但更新条件明确的局部块
4. 大列表和复杂页面优化
4.1 虚拟列表
数据量很大时,真正的问题不是“JS 算不动”,而是 DOM 太多。
这时优先考虑:
- 虚拟滚动
- 分页
- 分段渲染
4.2 避免一个状态驱动整页重算
很多页面卡,是因为一个输入框改一次,整页很多区域都重新求值、重新 patch。
解决思路:
- 按业务边界拆组件
- 把局部状态留在局部
- 避免把整页状态都堆进同一个超大响应式对象
4.3 缓存高成本页面
对列表页、搜索页、标签页这类频繁切换页面,可结合 keep-alive 做状态复用,减少重复初始化。
5. 静态资源优化
5.1 图片优化
- 优先控制原图尺寸
- 使用合适格式,例如 WebP、AVIF
- 非首屏图片懒加载
- 雪碧图或 Base64 只适合非常小的资源
5.2 字体优化
- 只引入需要的字重
- 大字体文件尽量分包或延迟加载
- 避免为了视觉细节加载过重的在线字体
5.3 CSS 优化
- 删除无用样式
- 控制全局样式体积
- 避免组件库样式全量覆盖式引入
6. 接口与数据层优化
前端性能不只是渲染。
很多“页面慢”的根因其实是:
- 接口瀑布流
- 重复请求
- 大 JSON 解析成本
- 请求时机过晚
常用手段:
- 并行请求
- 请求缓存
- 去重请求
- 首屏所需数据优先
- 非关键数据延迟拉取
7. Vite 项目里值得养成的分析习惯
不要凭感觉说“已经优化了”,最好有工具支撑。
常见思路:
- 用打包分析工具看 chunk 分布
- 看首屏网络 waterfall
- 看 Lighthouse 或 Web Vitals 指标
- 在 DevTools Performance 里看长任务和重渲染
优化应该是:
- 先测
- 再改
- 再复测
8. 常见误区
8.1 只盯着 Vite 配置
Vite 只是工具链。很多真正的性能问题来自:
- 组件边界设计差
- 状态范围太大
- 页面首屏塞太多业务逻辑
8.2 过度拆包
包拆得太碎,未必更快,可能只是把“大文件问题”换成“请求过多和缓存复杂问题”。
8.3 不区分开发性能和线上性能
开发期慢,不一定说明线上慢;线上首屏大,也不一定能靠 HMR 配置解决。要先区分问题所在阶段。
9. 面试高频答法
Q1:Vue + Vite 项目怎么做性能优化?
答:我会先分成开发期、构建产物、运行时三层。开发期主要看依赖预构建和 HMR 范围;构建产物主要做路由级懒加载、按需拆包和静态资源压缩;运行时主要控制组件边界、减少无效渲染、优化大列表和深度 watch。最后一定配合打包分析和性能面板验证效果。
Q2:Vite 已经很快了,为什么项目还是会卡?
答:因为 Vite 主要优化的是构建链路,不会自动解决业务层的无效渲染、大列表 DOM 数量、接口瀑布流、资源体积过大这些问题。工具快,不等于页面天然快。
速记要点
- 先分层:开发期、构建产物、运行时
- 首屏优化重点:路由懒加载、合理拆包、资源压缩
- 运行时重点:稳定 props、组件边界、虚拟列表、减少深度 watch
- 先分析再优化,不靠感觉