提升 Vue 项目(特别是 Vue 3)的性能需要在开发、构建和运行时多个层面进行优化。以下是经过实践验证的常用方法,涵盖代码优化、组件设计、构建配置以及运行时策略,帮助你降低内存占用、加快渲染速度并提升用户体验:
1. 代码层面的优化
组件优化
- 按需加载组件:
- 使用
defineAsyncComponent
实现动态导入,减少初次加载的代码量。 - 示例:
1const MyComponent = defineAsyncComponent(() => import('./MyComponent.vue'));
- 使用
- 减少不必要渲染:
- 使用
v-show
替代v-if
(仅隐藏而不销毁组件)。 - 使用
v-memo
(Vue 3.2+)缓存静态内容:
1<div v-memo="[items.length]"><div v-memo="[items.length]">{{ expensiveComputation() }}</div></div> - 使用
v-once
标记只渲染一次的元素。
- 使用
- 清理副作用:
- 在
onUnmounted
中移除事件监听器和定时器,避免内存泄漏:
1<div v-memo="[items.length]">onUnmounted(() => {<br> window.removeEventListener('resize', handleResize);<br> clearInterval(timer);<br>});</div>
- 在
数据管理
- 优化 reactive 和 ref:
- 避免对大数据对象使用
reactive
,改用ref
或普通对象,只代理必要部分:
1const largeData = ref(null); // 仅包装关键数据 - 使用
shallowReactive
或shallowRef
减少深层代理开销:
1const state = shallowReactive({ nested: { a: 1 } });
- 避免对大数据对象使用
- 计算属性(computed):
- 用
computed
缓存复杂计算,避免重复执行:
1const filteredList = computed(() => list.value.filter(item => item.active));
- 用
2. 渲染性能提升
虚拟列表
- 对于大数据列表(如表格),使用虚拟滚动技术,只渲染可视区域:
- 推荐库:
vue-virtual-scroll-list
或@vueuse/core
的虚拟滚动工具。 - 示例:
1<virtual-list :size="30" :remain="8" :items="largeList" />
- 推荐库:
分页加载
- 将大数据拆分为分页加载,配合后端 API:
1 2 3 4 5 6 7 |
const page = ref(1); const pageSize = 20; const tableData = ref([]); async function loadData() { const res = await fetch(`/api/data?page=${page.value}&size=${pageSize}`); tableData.value = await res.json(); } |
避免频繁 DOM 操作
- 使用
nextTick
确保 DOM 更新批量执行:
1 2 3 4 5 6 |
import { nextTick } from 'vue'; async function updateData() { data.value = newData; await nextTick(); // 等待 DOM 更新完成 console.log('DOM updated'); } |
3. 构建优化
打包工具配置
- Tree Shaking:
- 确保 Vite 或 Webpack 开启 Tree Shaking,移除未使用的代码。
- Vite 默认支持,Webpack 需配置
sideEffects
:
1{ "sideEffects": false }
- 分包加载:
- 使用
manualChunks
(Vite)或splitChunks
(Webpack)分离第三方库:
123456789101112// vite.config.jsexport default {build: {rollupOptions: {output: {manualChunks: {'vendor': ['vue', 'axios']}}}}};
- 使用
- 压缩资源:
- 启用生产模式压缩 JS、CSS 和图片:
123456// vite.config.jsimport { defineConfig } from 'vite';import viteCompression from 'vite-plugin-compression';export default defineConfig({plugins: [viteCompression()]});
- 启用生产模式压缩 JS、CSS 和图片:
按需引入第三方库
- 避免全局引入,例如
element-plus
:
1 2 |
import { ElButton, ElTable } from 'element-plus'; app.use(ElButton).use(ElTable); |
4. 运行时性能优化
Web Worker
- 将复杂计算(如数据排序、过滤)移到 Web Worker,减轻主线程负担:
1 2 3 |
const worker = new Worker('/worker.js'); worker.postMessage(largeData); worker.onmessage = (e) => console.log('Result:', e.data); |
路由优化
- 懒加载路由:
- 使用动态导入减少初始加载:
123456const routes = [{path: '/dashboard',component: () => import('./views/Dashboard.vue')}];
- 使用动态导入减少初始加载:
- 控制 keep-alive:
- 限制缓存组件数量,避免内存占用过高:
123<keep-alive :max="10"><router-view /></keep-alive>
- 限制缓存组件数量,避免内存占用过高:
CDN 加速
- 将 Vue、Element Plus 等静态资源通过 CDN 加载,减少本地打包体积:
1 |
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> |
5. 服务端配合
- 减少前端负担:
- 将数据处理(如过滤、排序)交给后端 API,前端只负责展示。
- 启用压缩:
- 配置服务器使用 Gzip 或 Brotli 压缩响应数据:
12gzip on;gzip_types application/javascript text/css;
- 配置服务器使用 Gzip 或 Brotli 压缩响应数据:
- 缓存策略:
- 对静态资源设置强缓存(
Cache-Control: max-age=31536000
),对 API 数据设置协商缓存。
- 对静态资源设置强缓存(
6. 性能监控与验证
- 使用工具验证优化效果:
- Vue Devtools:检查组件渲染时间。
- Lighthouse:分析页面加载性能。
- Chrome Performance:记录运行时开销。
- 生产环境监控:
- 集成 Sentry 或自定义日志,跟踪慢请求和内存峰值。
示例:优化一个大数据表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<template> <el-table :data="displayData" v-memo="[page.value]"> <el-table-column prop="id" label="ID" /> <el-table-column prop="name" label="Name" /> </el-table> <el-pagination v-model:current-page="page" :page-size="pageSize" :total="total" /> </template> <script setup> import { ref, computed, onMounted } from 'vue'; const tableData = ref([]); const page = ref(1); const pageSize = 20; const total = ref(0); const displayData = computed(() => { const start = (page.value - 1) * pageSize; return tableData.value.slice(start, start + pageSize); }); onMounted(async () => { const res = await fetch('/api/large-data'); tableData.value = await res.json(); total.value = tableData.value.length; }); </script> |
- 使用分页和
computed
减少渲染数据量。 - 用
v-memo
缓存表格内容。
总结
- 轻量化:按需加载、减少冗余代码。
- 高效渲染:虚拟列表、分页、缓存计算。
- 构建优化:分包、压缩、CDN。
- 运行时:Web Worker、路由优化。