Vue 页面频繁重渲染,性能为什么这么差?
2026/7/26 18:55:50 网站建设 项目流程

文章目录

    • 前言
    • 什么是“无意义的重渲染”?
      • 常见场景
    • Vue 响应式是如何“牵一发动全身”的?
      • 问题根源
    • computed / watch 用错,是性能杀手
      • 错误示例
      • 正确做法
    • v-memo:Vue 3 的“性能核武器”
      • 示例
    • shallowRef:大对象的救命稻草
      • 普通 ref
      • shallowRef
    • 拆分组件粒度,才是真正的解法
      • 问题代码
      • 优化思路
    • 实战:减少 70% 重渲染次数

前言

如果说长列表卡是“肉眼可见的慢”,那重渲染问题就是那种:

页面不卡,但 CPU 飙高
操作没问题,但风扇狂转

而且这种问题,非常隐蔽

什么是“无意义的重渲染”?

简单说一句:

数据没变,但组件又 render 了一遍。

常见场景

  • 父组件 state 变化
  • 子组件全部跟着重新执行 setup / render
  • computed / watch 被反复触发

Vue 响应式是如何“牵一发动全身”的?

Vue 的响应式是依赖收集 + 派发更新

问题根源

conststate=reactive({user:{name:'',age:0},settings:{theme:'dark'}})

如果你在组件里这样用:

state.user.name

一旦state.user发生变化,整个依赖都会被标记为脏

computed / watch 用错,是性能杀手

错误示例

watch(state,()=>{doSomethingHeavy()},{deep:true})

问题:

  • 任意字段变化都会触发
  • 深度监听成本极高

正确做法

watch(()=>state.user.name,()=>{doSomething()})

监听越精确,性能越好。

v-memo:Vue 3 的“性能核武器”

v-memo可以直接告诉 Vue:

这个组件,只在某些依赖变化时才重新渲染。

示例

<div v-memo="[item.id]"> {{ item.name }} </div>

只要item.id不变,这个节点就不会重新渲染。

shallowRef:大对象的救命稻草

普通 ref

constdata=ref(hugeObject)

Vue 会递归追踪所有字段。

shallowRef

constdata=shallowRef(hugeObject)

只关心引用变化,不追踪内部结构

适合:

  • 大列表数据
  • 三方 SDK 返回对象
  • 不需要深度响应的数据

拆分组件粒度,才是真正的解法

问题代码

<BigList :list="list" />

父组件任何更新,BigList都会重新渲染。

优化思路

  • 拆成 Item 组件
  • 用 props 精确传递
  • 避免无关 state 传递

实战:减少 70% 重渲染次数

通过:

  • 精准 watch
  • v-memo
  • shallowRef
  • 组件拆分

实测:

  • render 次数下降 ~70%
  • CPU 占用明显下降
  • 页面交互更稳定

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询