在前端工程化日趋成熟的今天,项目性能直接决定用户体验和产品留存率。Vue3搭配Vite作为当下主流的前端开发组合,凭借超快的热更新和编译速度收获大量开发者青睐,但随着项目业务迭代、依赖包增多,很容易出现打包体积过大、首屏加载缓慢、运行时卡顿等问题。
本文将从构建打包优化、运行时性能优化、资源加载优化、代码层面优化四个维度,梳理Vue3+Vite项目全链路性能优化方案,全部搭配实战代码和实操步骤,看完直接落地到项目,轻松实现项目体积缩减50%+、首屏加载速度提升60%+。
适用场景:Vue3.2+、Vite4.x+、Composition API项目,包含PC端管理后台、移动端H5、小程序内嵌H5等各类Vue3工程化项目
一、前置准备:性能问题排查工具
优化之前,首先要精准定位性能瓶颈,避免盲目优化。推荐两款掘金社区高频使用、上手零成本的排查工具:
1.1 Vite打包分析插件
通过可视化图表查看打包后各依赖包和文件体积,快速定位大包依赖,是优化打包体积的核心工具。
安装与配置
# 安装依赖
npm install rollup-plugin-visualizer -D
# 或者yarn
yarn add rollup-plugin-visualizer -D
在vite.config.js中引入配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 引入打包分析插件
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
vue(),
// 打包分析配置,生成stats.html可视化文件
visualizer({
open: true, // 打包完成后自动打开浏览器
gzipSize: true, // 显示gzip压缩后体积
brotliSize: true // 显示brotli压缩后体积
})
],
build: {
// 生产环境构建配置
sourcemap: false // 关闭sourcemap,减小打包体积
}
})
执行npm run build,会自动生成stats.html文件,打开后就能清晰看到各模块体积占比,重点关注体积超过100KB的依赖包。
1.2 Chrome DevTools性能排查
- Network面板:查看资源加载时长、体积、并发数,定位慢加载资源和冗余资源
- Performance面板:录制页面运行时性能,查看FP、FCP、LCP等核心性能指标,定位长任务和渲染卡顿
- Lighthouse:一键生成性能报告,获取性能评分和优化建议,掘金文章必备性能参考依据
二、构建打包优化:减小产物体积是核心
Vite基于Rollup构建,生产环境打包优化主要围绕代码分割、依赖分包、压缩、剔除冗余代码展开,这是提升首屏加载速度的关键。
2.1 依赖按需引入,杜绝全量打包
项目中常用的Element Plus、Ant Design Vue、ECharts等UI库和图表库,全量引入会导致打包体积暴增,必须改用按需引入。
Element Plus按需引入实战
# 安装按需引入插件
npm install unplugin-vue-components unplugin-auto-import -D
vite.config.js配置:
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
// 自动导入API
AutoImport({
resolvers: [ElementPlusResolver()],
// 自动导入Vue、VueRouter等核心API,无需手动import
imports: ['vue', 'vue-router', 'pinia']
}),
// 自动导入组件
Components({
resolvers: [ElementPlusResolver()]
})
]
})
配置完成后,无需在main.js全局引入Element Plus,组件和API会自动按需导入,打包体积可缩减60%以上。
2.2 代码分割与路由懒加载
Vue3路由默认全量加载,首屏会加载所有路由组件,导致加载缓慢,通过路由懒加载实现组件按需加载,拆分打包chunk。
路由懒加载配置
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
// 非首页组件全部采用懒加载
const routes = [
{
path: '/',
name: 'Home',
component: () => import('@/views/home/index.vue') // 懒加载
},
{
path: '/user',
name: 'User',
component: () => import('@/views/user/index.vue'),
// 嵌套路由同样懒加载
children: [
{ path: 'info', component: () => import('@/views/user/info.vue') }
]
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
同时在vite.config.js配置chunk拆分规则,避免单个chunk体积过大:
build: {
rollupOptions: {
output: {
// 拆分chunk,第三方依赖单独打包
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor' // 所有第三方依赖打包为vendor.js
}
// 进一步拆分大体积依赖
if (id.includes('echarts')) {
return 'echarts'
}
if (id.includes('element-plus')) {
return 'element-plus'
}
}
}
}
}
2.3 开启Gzip/Brotli压缩,大幅减小资源体积
静态资源开启压缩后,体积可缩减60%-80%,Vite可直接配置生成压缩文件,配合Nginx配置生效。
npm install vite-plugin-compression -D
import viteCompression from 'vite-plugin-compression'
plugins: [
// 开启gzip压缩
viteCompression({
algorithm: 'gzip', // 压缩算法
threshold: 10240, // 大于10KB的文件才压缩
deleteOriginFile: false // 不删除源文件
}),
// 开启brotli压缩(压缩率更高,优先使用)
viteCompression({
algorithm: 'brotliCompress',
threshold: 10240
})
]
2.4 剔除生产环境冗余代码
- 关闭生产环境console.log和debugger,避免调试代码上线
- 剔除未使用的CSS代码,减少样式文件体积
build: {
// 剔除console和debugger
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
// 剔除未使用CSS
cssCodeSplit: true,
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[hash][extname]'
}
}
}
三、运行时性能优化:解决页面卡顿问题
除了打包体积,运行时渲染卡顿、响应延迟是影响用户体验的另一大痛点,Vue3基于Proxy响应式,本身性能优于Vue2,但不合理的代码写法仍会导致性能损耗。
3.1 合理使用响应式API,避免过度响应式
Vue3的ref、reactive、computed、watch是核心响应式API,错误使用会导致不必要的重新渲染,优化原则:
- 基础数据类型用ref,引用类型用reactive,避免深层嵌套响应式
- 只读数据不用响应式,直接用const定义
- computed替代冗余的方法计算,缓存计算结果
- watch加immediate和deep慎用,避免不必要的监听
错误写法VS优化写法
<template>
<div>{{ totalPrice }}</div>
</template>
<script setup>
import { ref, computed } from 'vue'
// 错误:用方法计算,每次渲染都会重新执行
const price = ref(100)
const num = ref(2)
const getTotalPrice = () => price.value * num.value
// 优化:用computed缓存结果,仅依赖变化时重新计算
const totalPrice = computed(() => price.value * num.value)
</script>
3.2 长列表虚拟滚动,避免DOM过载
后台系统常见的长列表、大数据表格,直接渲染全部DOM会导致页面卡死,使用虚拟滚动只渲染可视区域DOM,大幅提升渲染性能。
推荐Vue3虚拟滚动库:vue-virtual-scroller、vxe-table(适配表格)
3.3 组件懒加载与keep-alive合理使用
- 非首屏必要组件,用defineAsyncComponent异步懒加载
- keep-alive缓存高频切换组件,避免重复渲染,搭配include、exclude精准控制缓存
<template>
<!-- 只缓存首页和用户页组件 -->
<keep-alive include="Home,User">
<router-view />
</keep-alive>
<!-- 异步懒加载非必要组件 -->
<AsyncModal v-if="showModal" />
</template>
<script setup>
import { defineAsyncComponent } from 'vue'
// 异步懒加载弹窗组件,点击时才加载
const AsyncModal = defineAsyncComponent(() => import('@/components/Modal/index.vue'))
const showModal = ref(false)
</script>
3.4 事件节流防抖,优化高频触发操作
搜索框输入、页面滚动、窗口 resize、按钮频繁点击等高频事件,不加节流防抖会导致函数频繁执行,引发卡顿,封装通用节流防抖工具函数。
// utils/debounce-throttle.js
// 防抖:触发后n秒内只执行一次,重复触发重新计时
export function debounce(fn, delay = 300) {
let timer = null
return function (...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
// 节流:n秒内只执行一次,稀释执行频率
export function throttle(fn, interval = 500) {
let lastTime = 0
return function (...args) {
const now = Date.now()
if (now - lastTime >= interval) {
lastTime = now
fn.apply(this, args)
}
}
}
四、资源加载优化:提升首屏加载速度
4.1 图片资源极致优化
- 图片压缩:使用tinypng压缩图片,生产环境禁用原图
- 图片懒加载:使用v-lazy指令,非可视区域图片延迟加载
- WebP格式替换:WebP体积比JPG/PNG小30%,兼容性好
- CDN加速:静态图片、字体、第三方资源改用CDN加载,分担服务器压力
Vue3图片懒加载配置
npm install vue3-lazy -D
// main.js
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'
const app = createApp(App)
app.use(lazyPlugin, {
loading: 'loading.png', // 加载中占位图
error: 'error.png' // 加载失败占位图
})
app.mount('#app')
<!-- 图片懒加载使用 -->
<img v-lazy="item.imgUrl" alt="商品图片" />
4.2 第三方资源CDN引入,脱离本地打包
Vue、VueRouter、Pinia、Axios等核心依赖,改用CDN引入,不参与本地打包,大幅减小vendor体积。
// vite.config.js
build: {
rollupOptions: {
// 外部化依赖,不打包
external: ['vue', 'vue-router', 'axios'],
output: {
// CDN全局变量映射
globals: {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios'
}
}
}
}
在index.html中引入CDN资源:
<!-- vue3 cdn -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.0/dist/vue.global.prod.js"></script>
<!-- vue-router cdn -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@4.2.0/dist/vue-router.global.prod.js"></script>
五、优化效果复盘与核心指标
按照以上方案优化后,通过Lighthouse检测和打包分析,可实现以下效果:
- 打包整体体积缩减50%-70%,Gzip压缩后体积进一步减小
- 首屏加载时间(LCP)从3-5s优化至1s以内
- 页面运行时无长任务,卡顿率降低90%
- Lighthouse性能评分从60分提升至90分以上
六、总结与避坑要点
- 优化优先级:先排查打包体积 → 再优化首屏加载 → 最后解决运行时卡顿,循序渐进
- 避免过度优化:小型项目无需复杂分包,按需配置,避免增加工程复杂度
- 兼容性考量:Brotli压缩、WebP图片需确认服务器和客户端兼容性,做好降级方案
- 持续监控:项目迭代后定期用打包分析和Lighthouse检测,及时发现新增性能问题
Vue3+Vite项目性能优化没有统一标准,核心是按需加载、减少冗余、提升渲染效率。本文的优化方案均经过线上项目验证,可直接复制代码落地,适合各类Vue3工程化项目参考。
如果觉得本文对你有帮助,欢迎点赞、收藏、评论,后续会持续更新Vue3+Vite实战干货,关注我不迷路~
作者:前端技术博主
链接:本文首发于掘金,转载请注明出处