您现在的位置是:首页 >技术杂谈 >Vue3 性能优化之shallowReactive和shallowRef网站首页技术杂谈

Vue3 性能优化之shallowReactive和shallowRef

阿丽塔~ 2026-02-27 12:01:03
简介Vue3 性能优化之shallowReactive和shallowRef

Vue的响应式系统默认是深度的。虽然这让状态管理变得更直观,但在数据量巨大时,深度响应性也会导致不小的性能负担,因为每个属性访问都将出发代理的依赖追踪。好在这种性能负担通常只有在处理超大型数组或层级很深的对象时,例如:一次渲染需要访问100,000+个属性时,才会变得比较明显。因此,他只会影响少数特定的场景。

vue确实也为此提供了一种解决方案,通过使用 shallowRef() shallowReactive() 来绕开深度响应。

浅层和深层的对比:

1.浅层(shallow)

定义:只对数据结构的最外层进行操作或跟踪。对于嵌套的属性或者对象,不会递归地追踪其内部的变化。

应用:在需要优化性能时,减少不必要的深层次数据追踪,比如:shallowRef 和 shallowReactive 提供了这种功能。

优点:提高性能,减少Vue 内部的深度响应式追踪,特别是在数据结构复杂时效果显著

缺点:无法自动跟踪嵌套对象或数组内部的变化,需要手动处理或选择其他方式

2.深层(deep)

定义:对数据结构的所有层级都进行操作或跟踪。递归地追踪嵌套的对象或数组中的所有属性。

应用:在需要全面跟踪数据变化时,例如使用 reactive 进行深层响应式追踪。。

优点:能够自动跟踪嵌套的所有属性变化,确保数据的每一层都响应式。

缺点:性能开销较大,特别是在数据结构非常复杂或庞大时。

浅层式API(shallowRef 和 shallowReactive)创建的状态只在其顶层是响应式的对所有深层的对象不会做任何处理,这使得对深层级属性的访问变得更快,但代价是,我们现在必须将所有深层级对象视为不可变的,并且只能通过替换整个根状态来触发更新:

接下来详细介绍下这两个浅层式AP:

shallowRef:

功能:创建一个浅层响应式引用,只对引用值的第一层数据变化进行响应式处理,不会递归追踪嵌套对象的变化

使用场景:

  • 当处理复杂数据结构,但只关心顶层数据的变化时,使用 shallowRef 可以避免不需要的深层次响应式追踪
  • 适用于需要优化性能的场景,尤其是当数据结构非常复杂或庞大时
const user = shallowRef({
  name: 'Alice',
  age: 30,
  address: {
    city: 'San Francisco',
    state: 'CA'
  }
});
watchEffect(()=>{
  console.log(user.value)
})
user.value.name = 'Bob'; // 不触发响应式更新
user.value = { name: 'Bob', age: 35 }; // 触发响应式更新

triggerRef是一个用于触发响应式更新的工具,主要用于与 shallowRef 配合使用。triggerRef 方法用于强制触发对shallowRef的响应式更新当你需要对shallowRef的内层属性进行操作,并希望这些操作触发响应式更新时,可以使用triggerRef

const shallow = shallowRef({
  greet: 'Hello, world'
})

// 触发该副作用第一次应该会打印 "Hello, world"
watchEffect(() => {
  console.log(shallow.value.greet)
})

// 这次变更不应触发副作用,因为这个 ref 是浅层的
shallow.value.greet = 'Hello, universe'

// 打印 "Hello, universe"
triggerRef(shallow)

shallowReactive:

功能:创建一个浅层响应式对象,只对对象的第一层属性进行响应式处理,不会递归的将嵌套对象的熟悉也变成响应式

使用场景:

  • 当处理复杂嵌套对象时,但只关心对象的第一层属性变化,使用shallowReactive可以显著减少性能开销
  • 避免对嵌套对象的深层次属性进行不必要的响应式追踪,从而优化性能
const user = shallowReactive({
  name: 'John',
  age: 25,
  address: {
    city: 'New York',
    country: 'USA'
  }
});
user.name = 'Jane'; // 触发响应式更新
user.address.city = 'Los Angeles'; // 不触发响应式更新

总结:

性能优化:shallowRef 和 shallowReactive 通过减少不必要的深度响应式追踪,显著提高了性能

使用场景:当不需要嵌套对象的深层次属性进行响应式处理时,使用它们可以避免不必要的性能开销

注意事项:如果需要对嵌套属性进行响应式处理,则应使用reactive 或 ref 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。