背景
一个音讯列表中,有个计时的数据,每秒都会更新。当应用 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