react如何通过shouldComponentUpdate来减少重复渲染
在react开发中,经常会遇到组件重复渲染的问题,父组件一个state的变化,就会导致以该组件的所有子组件都重写render,尽管绝大多数子组件的props没有变化
render什么时候会触发
首先,先上一张react生命周期图:
这张图将react的生命周期分为了三个阶段:生成期、存在期、销毁期,这样在create、props、state、unMount状态变化时我们可以清楚的看到reacte触发了哪些生命周期钩子以及什么时候会render。
如果我们需要更改root的一个state,使绿色组件视图更改:
如果你写过vue,你会发现组件更新是如上图那样的(视图指令已编译为修改视图的函数存放在绑定的state里的属性里,所以能够做到靶向修改),而react会以组件为根,重新渲染整个组件子树,如下图(绿色是期望的render路径,橙色是无用render):
所以在react里,我们探讨的render性能优化是react调用render的路径如下:
如何避免这些不必要的render:
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState)
使用shouldComponentUpdate()以让React知道当前状态或属性的改变是否不影响组件的输出,默认返回ture,返回false时不会重写render,而且该方法并不会在初始化渲染或当使用forceUpdate()时被调用,我们要做的只是这样:
shouldComponentUpdate(nextProps, nextState) {
return nextState.someData !== this.state.someData
}
但是,state里的数据这么多,还有对象,还有复杂类型数据,react的理念就是拆分拆分再拆分,这么多子组件,我要每个组件都去自己一个一个对比吗??不存在的,这么麻烦,要知道我们的终极目标是不劳而获-_-
React.PureComponent
React.PureComponent 与 React.Component 几乎完全相同,但 React.PureComponent 通过props和state的浅对比来实现 shouldComponentUpate()。如果对象包含复杂的数据结构,它可能会因深层的数据不一致而产生错误的否定判断(表现为对象深层的数据已改变视图却没有更新)
关注点:
关注点:
- 无论组件是否是 PureComponent,如果定义了 shouldComponentUpdate(),那么会调用它并以它的执行结果来判断是否 update。在组件未定义 shouldComponentUpdate() 的情况下,会判断该组件是否是 PureComponent,如果是的话,会对新旧 props、state 进行 shallowEqual 比较,一旦新旧不一致,会触发 update。
- 浅判等 只会比较到两个对象的 ownProperty 是否符合 Object.js() 判等,不会递归地去深层比较---源码
const hasOwnProperty = Object.prototype.hasOwnProperty; /**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x: mixed, y: mixed): boolean {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
// Added the nonzero y check to make Flow happy, but it is redundant
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
} /**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA: mixed, objB: mixed): boolean {
if (is(objA, objB)) {
return true;
} if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false;
} const keysA = Object.keys(objA);
const keysB = Object.keys(objB); if (keysA.length !== keysB.length) {
return false;
} // Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
} return true;
}
- 至于复杂数据结构,用Object.key()获取下key,然后key和对应的value都是基础类型数据,就是算是简单数据结构,不然就是复杂
针对以上规则我们在项目开发种可以做出如下优化:
尽量将复杂类型数据(ArrayList)所关联的视图单独拆成PureComonent有助于提高渲染性能,比如表单、文本域和复杂列表在同一个 render() 中,表单域的输入字段改变会频繁地触发 setState() 从而导致 组件 重新 render()。而用于渲染复杂列表的数据其实并没有变化,但由于重新触发 render(),列表还是会重新渲染。
react-immutable-render-mixin
我想复杂数组没变化时也不要render(), 那你用react-immutable-render-mixin,来,我们看看插件的介绍:
Users are urged to use PureRenderMixin with facebook/immutable-js. If performance is still an issue an examination of your usage of Immutable.js should be your first path towards a solution. This library was created from experimentations with Immutable that were ultimately erroneous; improper usage of Immutable.js
react如何通过shouldComponentUpdate来减少重复渲染的更多相关文章
- 【react】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的必要性
凡是参阅过react官方英文文档的童鞋大体上都能知道对于一个组件来说,其state的改变(调用this.setState()方法)以及从父组件接受的props发生变化时,会导致组件重渲染,正所谓&qu ...
- Random获得的随机数怎么样减少重复率
C#中的Random在获得随机数的时,如果你想要随机循环取得100个随机数则使用如下代码会出现大量的重复数字.代码如下: using System; namespace ConsoleApplicat ...
- 翻译 | 关键CSS和Webpack: 减少阻塞渲染的CSS的自动化解决方案
原文地址: Critical CSS and Webpack: Automatically Minimize Render-Blocking CSS 原文作者: Anthony Gore 译者: 蜗牛 ...
- ionic ngRepeat追加数据(加载更多,不需要重复渲染dom数据)
1)模版循环在之前的随笔中已经说过,使用挺简单的 http://www.cnblogs.com/tujia/p/6078217.html 简单来说就是控制器输入一个数据变量,模版里用ng-repeat ...
- 编写高质量代码改善C#程序的157个建议——建议98:用params减少重复参数
建议98:用params减少重复参数 如果方法的参数数目不定,且参数类型一致,则可以使用params关键字减少重复参数声明. void Method1(string str, object a){} ...
- 微信小程序-wepy-组件模板重复渲染
微信小程序开发,有使用wepy框架的需求.上手: 安装自己可以到官网查看,飞机票:https://tencent.github.io/wepy/document.html#/ 具体开发模式和Vue开发 ...
- Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写(全部用POSIX C实现)
Light libraries是一组通用的C基础库,目标是为减少重复造轮子而写实现了日志.原子操作.哈希字典.红黑树.动态库加载.线程.锁操作.配置文件.os适配层.事件驱动.工作队列.RPC.IPC ...
- 关键CSS和Webpack: 减少阻塞渲染的CSS的自动化解决方案
原文地址: Critical CSS and Webpack: Automatically Minimize Render-Blocking CSS 原文作者: Anthony Gore 译者: 蜗牛 ...
- React Router 按需加载+服务器渲染的闪屏问题
伴随着React协议的『妥协』(v16采用MIT),React为项目的主体,这个在短期内是不会改变的了,在平时使用过程中发现了如下这个问题: 在服务器渲染的时候,刷新页面会出现闪屏的现象(白屏一闪而过 ...
随机推荐
- 8,聚类分析 fenxinhuag
1.K-Means聚类分析 2.系统聚类分析 样本间常用距离: 类间常用距离: 3.DBSCAN聚类分析
- vue生命周期updated的触发时机之debug过程中发现的firefox问题
现象描述: 断点位置1 谷歌debug的过程: 火狐debug的过程: 只要在改变数据之后有断点停顿,就会先去执行updated函数 断点位置2 此时火狐和谷歌是一样的效果,但是执行顺序是不一致的 谷 ...
- Maven打包时出现无法下载org.apache.maven.plugins插件
解决方式: 方式1:使用 mvn clean package -U 打包即可(注意:出于性能原因,Maven缓存插件无法下载的信息.根据您的设置,您可能需要通过将标志添加-U到命令行来清除此缓存,以使 ...
- 使用jdk自带工具jvisualvm 分析内存dump文件
1.获取dump文件 使用 以下命令 创建 进程PID = 16231的 dump文件,命名为 order.hprof jmap -dump:format=b,file=order.hprof 162 ...
- C#在非UI线程调用UI线程的控件
首先需要定义一个委托(delegate): private delegate void delegateSetProcessBarVal(int value); 然后定义一个方法来执行具体的操作: p ...
- (C#)Appium自动化测试之卸载\重装APP
1.先获取session,实例化driver 2.自动安装APP //安装driver.InstallApp("APP的路径"); //判断是否安装完成,返回true\false ...
- Tensorflow 多层全连接神经网络
本节涉及: 身份证问题 单层网络的模型 多层全连接神经网络 激活函数 tanh 身份证问题新模型的代码实现 模型的优化 一.身份证问题 身份证号码是18位的数字[此处暂不考虑字母的情况],身份证倒数第 ...
- 当C++使用引用传递参数时,应当注意的问题
如果实参与引用参数不匹配,C++将生成临时变量.如果引用参数是const,则编译器在下面两种情况下生成临时变量: 实参类型是正确的,但不是左值 实参类型不正确,但可以转换为正确的类型 左值参数是可被引 ...
- 【Aizu - 0558】Cheese(bfs)
-->Cheese 原文是日语,这里就写中文了 Descriptions: 在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪.有一只老鼠准备从出发点吃遍每一个工厂的奶酪.老 ...
- Pytorch修改ResNet模型全连接层进行直接训练
之前在用预训练的ResNet的模型进行迁移训练时,是固定除最后一层的前面层权重,然后把全连接层输出改为自己需要的数目,进行最后一层的训练,那么现在假如想要只是把 最后一层的输出改一下,不需要加载前面层 ...