背景
一个消息列表中,有个计时的数据,每秒都会更新。当使用Vue Devtool Flash Updates
插件观察组件update时机时,发现不论列表中的某个子项数据是否有变动,都会导致整个列表重新update(下图)。由于update时里面子组件都会重新update,再加上每秒计时导致整个列表的性能收到影响。
期望是如果有某个子项计时数据变动,那应该只更新某个子项,期望如下图
排查过程
方向:检查父子组件的传递中是否有其他props导致了变动,逐个排除属性
- 结果:发现并没有属性能够影响组件本身,只剩列表数组本身,还是会触发
方向:对列表到子项中的各个组件手动做useMemo处理
- 结果:从内到外都做了缓存,发现几十父组件缓存,其中一个数组元素变动,子组件收到的列表还是会受影响
方向:检查vuex中state getters数据变动,组件内state,getters的异同,看是否会引起不必要的更新
- Vuex排查结果:vuex的getters中的日期时间数据会引起不必要的刷新,导致即使没有计时显示也会每秒update,改造成变动时再修改vuex state。可以解决问题。
- Vue排查结果:如果只是组件state里的数组元素的某个属性修改,是局部更新的。但如果是数组中的一个元素被修改,列表还是会整个update
结论
关于 Array<Object> 列表渲染:
- Vue.$set( state.arr , i , val ) 会触发整个列表组件的update
- 改为Vue.$set( state.arr[i] , k , val ) 则不会
关于 Vuex 的 getters :
- getters依赖的getters更新,不像react有useMemo机制,即使基础类型值不变也会触发update
- getters依赖的state更新,基础类型值不变不会触发update
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。