您现在的位置是:首页 >技术杂谈 >Vue3 性能优化之shallowReactive和shallowRef网站首页技术杂谈
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





QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
U8W/U8W-Mini使用与常见问题解决
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结