Vue 性能优化指南:虚拟列表、懒加载、渲染优化与 Core Web Vitals

Vue 3 应用性能优化完整策略:虚拟滚动(vue-virtual-scroller)、组件懒加载与异步组件、KeepAlive 缓存、Suspense 异步优化、v-memo 渲染记忆化、响应式性能(shallowRef/toRaw)、Bundle 分析与代码分割、渲染函数优化、以及 Core Web Vitals(LCP/INP/CLS)调优。

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.5sSSR/SSG(Nuxt)、图片懒加载 <NuxtImg>
INP< 200ms分解长任务、Web Workers
CLS< 0.1骨架屏、图片尺寸预设
TTFB< 600msEdge Functions、CDN

常见问题(FAQ)

Vue 3 比 Vue 2 快多少?

  • 编译时优化:静态提升 + 补丁标志
  • 响应式:Proxy 比 defineProperty 快 2-10 倍
  • Bundle:运行时减少 41%
  • 整体:大多数场景快 1.3-2 倍

什么时候用 v-memo?

大数据列表中,当列表项的渲染成本远高于判断成本时。普通列表不需要。

相关阅读

下一篇 →

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「frontend」更多文章