Vue 3 默认性能已大幅优于 Vue 2,但生产级应用仍需针对具体场景进行调优。本文覆盖从大数据渲染到 Bundle 优化的完整性能策略。
一、大数据列表:虚拟滚动
1.1 vue-virtual-scroller
<template>
<RecycleScroller
class="scroller"
:items="items"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div class="item">{{ item.name }}</div>
</RecycleScroller>
</template>
<script setup>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
const items = ref(Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `Item ${i}`,
})))
</script>
原理:只渲染可视区域 + 缓冲区的 DOM 节点(通常 20-30 个),滚动时动态复用。
二、懒加载与异步组件
<script setup>
import { defineAsyncComponent } from 'vue'
// 异步加载重型组件
const HeavyChart = defineAsyncComponent(() =>
import('./HeavyChart.vue')
)
// 带加载状态
const AsyncModal = defineAsyncComponent({
loader: () => import('./Modal.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorDisplay,
delay: 200, // 延迟显示 loading
timeout: 3000, // 超时时间
})
</script>
三、KeepAlive 缓存
<template>
<KeepAlive :include="['TabA', 'TabB']" :exclude="['TabC']" :max="10">
<component :is="activeTab" />
</KeepAlive>
</template>
场景:Tab 切换、搜索条件面板,避免重复创建和销毁组件。
四、v-memo 渲染记忆化
<template>
<!-- 只有 id 或 name 变化时才重新渲染 -->
<div v-memo="[item.id, item.name]">
<p>{{ item.name }}</p>
<p>{{ item.description }}</p> <!-- description 变化不触发重渲染 -->
</div>
</template>
五、响应式性能优化
5.1 shallowRef / shallowReactive
import { shallowRef } from 'vue'
// 大型对象不需要深度响应时
const bigData = shallowRef({ list: [/* 10000 items */] })
// 只有 bigData.value = newObj 触发更新
// bigData.value.list[0] = 'x' 不自动触发
5.2 toRaw:避免响应式开销
import { toRaw } from 'vue'
const state = reactive({ items: [] })
// 传递给外部库时,取消响应式包装(提升性能)
api.save(toRaw(state))
六、Bundle 分析与代码分割
# 分析 Bundle 体积
npm run build -- --analyze
# 或 rollup-plugin-visualizer
npm install -D rollup-plugin-visualizer
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor': ['vue', 'vue-router', 'pinia'],
'charts': ['echarts', 'recharts'],
},
},
},
},
plugins: [
visualizer({ open: true }),
],
})
七、Core Web Vitals 优化
| 指标 | 目标 | Vue 优化手段 |
|---|---|---|
| LCP | < 2.5s | SSR/SSG(Nuxt)、图片懒加载 <NuxtImg> |
| INP | < 200ms | 分解长任务、Web Workers |
| CLS | < 0.1 | 骨架屏、图片尺寸预设 |
| TTFB | < 600ms | Edge Functions、CDN |
常见问题(FAQ)
Vue 3 比 Vue 2 快多少?
- 编译时优化:静态提升 + 补丁标志
- 响应式:Proxy 比 defineProperty 快 2-10 倍
- Bundle:运行时减少 41%
- 整体:大多数场景快 1.3-2 倍
什么时候用 v-memo?
大数据列表中,当列表项的渲染成本远高于判断成本时。普通列表不需要。
相关阅读
- Vue 详解 — 核心概念
- Vue Composition API 完全指南 — computed/watch 的性能模式
- Nuxt.js 完全指南 — SSR/SSG 性能优化
- React 性能优化指南 — 跨框架性能对比
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「frontend」更多文章
Nuxt.js 完全指南:Vue 全栈框架的 SSR、SSG、API 路由与部署实践
Nuxt.js 3 深度实践:文件系统路由、SSR/SSG/ISR 渲染模式、API 路由(Server Routes)、useFetch/useAsyncData 数据获取、中间件与插件、SEO 与 Meta 管理、Nitro 服务端引擎、自动导入、部署到 Vercel/Netlify/Node.js。
Vue 测试深度指南:Vitest + Vue Test Utils + Playwright E2E 与 CI 集成
Vue 3 应用从单元测试到 E2E 的完整测试策略:Vitest + Vue Test Utils 组件测试(mount/emits/slots/async)、Pinia Store Mocking、MSW API 拦截、Playwright 端到端测试、Cypress 组件测试、覆盖率标准与 GitHub Actions CI 集成。
Vue + TypeScript 深度实战:组件类型、Props 泛型、Pinia 类型安全与 API 契约
Vue 3 与 TypeScript 结合的生产级实践:组件 Props 类型标注、defineProps 泛型、 emits 类型、ref/reactive 类型推断、computed 类型、Pinia Store 类型、Vue Router 类型安全、Zod API 数据契约、以及 strict tsconfig 配置。