如何有效地提高react渲染效率--深复制,浅复制,immutable原理
来源:互联网 发布:2016年淘宝双十一数据 编辑:程序博客网 时间:2024/06/05 00:21
1. 性能意义:保持state不变这个约束引导我们使用局部更新对象的方法,这样会可以非常有效地提高react或其他显示框架的渲染效率。我们先来看看为了保持数据不变性,要怎么对state做更新,以我们的苹果篮子state为例:
例子:通知开始摘苹果:apple/BEGIN_PICK_APPLE
为了保证每个版本的state不变性,我们有两种实现方式:“深复制”,“浅复制”。我们来看两种模式的内部原理:
深复制方式:有人会这样想:“保持state的不变性很容易,只需要深复制一个state, 让后在新的state要怎么修改就怎么修改,不ok了吗?”,如下就是深复制
这种方式是一种很低级保持不变性的方式:
深复制操作运行效率低
没有为渲染环节提供提高渲染效率的铺垫
它只是简单迎合保持数据不变性的约束,虽然有一定调试意义,但是,不但没有提高程序的性能,反而降低了程序的总体性能!没有实践意义。
浅复制方式:浅复制模式只对内部数据发生变化的引用做更新,如下
“state” 对象的内部数据发生变化,所以创建新的state引用;而apples array 内部数据不发生变化,所以就不对该引用做更新!在这个操作中,这种浅复制的方法运行效率比较高,而且其简单地实现了数据不变性,为调试带来方便,同时,也是更重要的,这种浅复制的方式极大地提高了视觉组件渲染阶段的运行效率!我们来对比一下:当用户点击摘苹果时,如果使用“深复制”,渲染程序需要重新遍历整个state对象树来做视觉更新,而使用浅复制来实现数据不变性时,渲染程序只需要遍历state对象的一级子节点即可,而不需要对apples array 做遍历,性能大大地提高。尤其是当苹果很多的时候,两种方式的性能差距是非常明显的。
备注:在react组件里面,要开启条件更新这个生命周期函数 shouldComponentUpdate, 才会对把这个性能提高点释放出来,类似这样:
...shouldComponentUpdate(nextProps) { return nextProps.state != this.props.state;}...
下面我们再给出 “吃苹果” reducer 进行浅复制的例子:
现在大家应该理解了用浅复制实现数据不变性的原理和意义了,下面我们来看具体的代码实现。
我们的代码用 es6 编写,这里要用到 es6 两个非常方便的特性:
Obejct.assign() 方法,该方法用于产生新的对象
延展操作符 Spread operator : ...
大家可以稍微看一下文档,或者看我下面的例子就知道其用法了:
// apple basket reducerexport default (state = { isPicking: false, newAppleId: 1, apples: [ { id: 0, weight: 235, isEaten: false } ]}, action) => { let newState ; switch (action.type) { case 'apple/BEGIN_PICK_APPLE': newState = Object.assign({}, state, { isPicking: true }); return newState; case 'apple/DONE_PICK_APPLE': newState = Object.assign({}, state, { apples: [ ...state.apples, { id: state.newAppleId, weight: action.payload, isEaten: false } ], newAppleId: state.newAppleId + 1, isPicking: false }) return newState; case 'apple/FAIL_PICK_APPLE': //这里只是简单处理 newState = Object.assign({}, state, { isPicking: false }); return newState; case 'apple/EAT_APPLE': newState = Object.assign({}, state, { apples: [ ...state.apples.slice(0, action.payload), Object.assign({}, state.apples[action.payload], { isEaten: true }), ...state.apples.slice(action.payload + 1) ] }) return newState; default: return state; }};
大家会发现这种浅复制操作在开发的过程会复杂一点,于是就有了 immutable.js 这个专门处理不变性数据的库(也是facebook出品),它可以使用类似赋值的方式生成浅复制的不变性数据,下面来看看它怎么简化我们的开发:
我们用 apple/EAT_APPLE
这个reducer来说明。
这是原来的 reducer:
...case 'apple/EAT_APPLE': newState = Object.assign({}, state, { apples: [ ...state.apples.slice(0, action.payload), Object.assign({}, state.apples[action.payload], { isEaten: true }), ...state.apples.slice(action.payload + 1) ] }) return newState;...
这是使用 immutable.js 库的reducer :
import { fromJS } from 'immutable';...case 'apple/EAT_APPLE': return fromJS(state).setIn(['apples',action.payload,'isEaten'], true).toJS();...
用了immutable.js后,轻松一行代码搞定!如果团队约定 state 都用 immutable 内部的数据类型,就可以连 fromJS 和 toJS 的转化都省了,超级方便!
到这里, reducer 任务的介绍就结束啦~
- 如何有效地提高react渲染效率--深复制,浅复制,immutable原理
- MySQL主从复制的常见拓扑、原理分析以及如何提高主从复制的效率总结
- MySQL主从复制的常见拓扑、原理分析以及如何提高主从复制的效率总结
- React中的浅复制与深复制
- php对象复制原理(浅复制和深复制)
- 浅复制&深复制
- 深复制、浅复制
- 浅复制&深复制
- 浅复制 & 深复制
- 深复制浅复制
- 深复制浅复制
- 深复制----浅复制
- 深复制&浅复制
- 浅复制--深复制
- 深复制、浅复制
- js浅复制与深复制的原理
- CCSpriteBatchNode提高渲染效率
- 提高css渲染效率
- Record
- tempo学习
- 【JAVA学习】——J2EE规范
- 275. H-Index II
- 超越fast style transfer----任意风格图和内容图0.1秒出结果
- 如何有效地提高react渲染效率--深复制,浅复制,immutable原理
- 嵌入式系统优点汇总
- iOS开发 Swift添加CocoaPods依赖库管理
- 技术点详解---网络中的身份保护与信息保护
- ssh 无法连接到Linux
- 如何让你的简历脱颖而出
- Gradle问题
- SpringSecurity-密码错误5次锁定用户
- win2003无法访问共享文件夹处理方法