Vue3 提供了多种性能优化方法,以下是一些常见的优化技巧:
1. 虚拟列表(Virtual Scrolling)
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
示例库:vue-virtual-scroller、vueuse/core
2. 组件懒加载(Async Components)
对于非关键组件或复杂组件,使用动态导入延迟加载:
<script setup>
import { defineAsyncComponent } from 'vue'
const HeavyComponent = defineAsyncComponent(() => import('./HeavyComponent.vue'))
</script>
3. 缓存组件(Keep-Alive)
使用 <Keep-Alive>
缓存频繁切换的组件,避免重复渲染:
<Keep-Alive>
<RouterView />
</Keep-Alive>
4. 事件监听器优化
- 在不需要响应式的地方使用普通函数而非箭头函数。
避免在循环中绑定事件处理器,可通过事件代理优化:
<div @click="handleClick"> <div v-for="item in list" :data-id="item.id">{ { item.name }}</div> </div> <script setup> const handleClick = (e) => { const id = e.target.dataset.id if (id) { // 处理点击逻辑 } } </script>
5. 计算属性缓存(Computed Caching)
利用计算属性的缓存特性,避免重复计算:
<script setup>
import { computed, ref } from 'vue'
const list = ref([1, 2, 3, 4, 5])
const evenNumbers = computed(() => list.value.filter(n => n % 2 === 0))
</script>
6. 避免响应式陷阱
对于大型静态数据(如常量配置),使用
markRaw()
避免转为响应式对象:import { markRaw } from 'vue' const largeStaticData = markRaw({ /* 大量数据 */ })
- 使用
shallowRef()
和shallowReactive()
创建浅层响应式对象。
7. 优化 v-for 指令
- 始终为
v-for
提供唯一的:key
。 - 避免在同一元素上同时使用
v-for
和v-if
(可通过计算属性过滤数据)。
8. 按需引入组件
对于大型组件库(如 Element Plus、Ant Design Vue),按需引入组件减少打包体积:
// vite.config.js
import {
defineConfig } from 'vite'
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: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
9. 优化响应式更新范围
- 使用
reactive()
替代ref()
包装复杂对象,减少嵌套层级。 - 避免深层响应式更新,可通过拆分组件或使用
toRefs()
解耦数据。
10. 生产环境优化
- 使用
vite
或webpack
等工具进行代码分割和 Tree-Shaking。 - 移除开发时的调试工具(如
console.log
、Vue DevTools 钩子):// vite.config.js export default defineConfig({ define: { __VUE_PROD_DEVTOOLS__: false, }, })
11. 服务端渲染(SSR)/ 静态站点生成(SSG)
对于内容型应用,使用 Vue Server Renderer
或 Nuxt.js
提升首屏加载速度。
12. 使用 VueUse 工具库
VueUse 提供了许多性能优化的组合式函数,如 useIntersectionObserver
实现懒加载:
<script setup>
import { useIntersectionObserver } from '@vueuse/core'
const target = ref(null)
const { stop } = useIntersectionObserver(
target,
([{ isIntersecting }]) => {
if (isIntersecting) {
// 元素进入视口时执行加载逻辑
stop() // 停止监听
}
}
)
</script>
<template>
<img ref="target" src="lazy-image.jpg" alt="懒加载图片" />
</template>
总结
根据应用场景选择合适的优化策略:
- 大量数据渲染:优先使用虚拟列表。
- 复杂组件:使用懒加载和缓存。
- 频繁更新:优化响应式对象和计算属性。
- 生产环境:做好打包优化和代码分割。
通过这些技巧,可以显著提升 Vue3 应用的性能和用户体验。