前面的话

  本文将详细介绍react性能优化

避免重复渲染

  当一个组件的props或者state改变时,React通过比较新返回的元素和之前渲染的元素来决定是否有必要更新实际的DOM。当他们不相等时,React会更新DOM。

  在一些情况下,组件可以通过重写这个生命周期函数shouldComponentUpdate来提升速度, 它是在重新渲染过程开始前触发的。 这个函数默认返回true,可使React执行更新:

shouldComponentUpdate(nextProps, nextState) {
return true;
}

  如果知道在某些情况下组件不需要更新,可以在shouldComponentUpdate内返回false来跳过整个渲染进程,该进程包括了对该组件和之后的内容调用render()指令

  如果想让组件只在props.color或者state.count的值变化时重新渲染,可以像下面这样设定shouldComponentUpdate

  shouldComponentUpdate(nextProps, nextState) {
if (this.props.color !== nextProps.color) {
return true;
}
if (this.state.count !== nextState.count) {
return true;
}
return false;
}

【pureComponent】

  在以上代码中,shouldComponentUpdate只检查props.colorstate.count的变化。如果这些值没有变化,组件就不会更新。当组件变得更加复杂时,可以使用类似的模式来做一个“浅比较”,用来比较属性和值以判定是否需要更新组件。这种模式十分常见,因此React提供了一个辅助对象来实现这个逻辑 - 继承自React.PureComponent。以下代码可以更简单的实现相同的操作:

class CounterButton extends React.PureComponent {
constructor(props) {
super(props);
this.state = {count: };
} render() {
return (
<button
color={this.props.color}
onClick={() => this.setState(state => ({count: state.count + }))}>
Count: {this.state.count}
</button>
);
}
}

  大部分情况下,可以使用React.PureComponent而不必写自己的shouldComponentUpdate,它只做一个浅比较。但是由于浅比较会忽略属性或状态突变的情况,此时不能使用它

避免突变

  PureComponent将会在this.props.words的新旧值之间做一个简单的比较。由于代码中words数组在WordAdderhandleClick方法中被改变了,尽管数组中的实际单词已经改变,this.props.words的新旧值还是相等的,因此即便ListOfWords具有应该被渲染的新单词,它还是不会更新。

  handleClick() {
// This section is bad style and causes a bug
const words = this.state.words;
words.push('marklar');
this.setState({words: words});
}

  避免此类问题最简单的方式是避免使用值可能会突变的属性或状态。例如,上面例子中的handleClick应该用concat重写成:

handleClick() {
this.setState(prevState => ({
words: prevState.words.concat(['marklar'])
}));
}

  或者使用展开运算符

handleClick() {
this.setState(prevState => ({
words: [...prevState.words, 'marklar'],
}));
};

  也可以用相似的方式重写可以会突变的对象。例如,假设有一个叫colormap的对象,我们想写一个把colormap.right改变成'blue'的函数,我们应该写:

function updateColorMap(colormap) {
colormap.right = 'blue';
}

  想要实现代码而不污染原始对象,我们可以使用Object.assign方法

function updateColorMap(colormap) {
return Object.assign({}, colormap, {right: 'blue'});
}

  或者使用扩展运算符

function updateColorMap(colormap) {
return {...colormap, right: 'blue'};
}

immutable

  Immutable.js是解决这个问题的另一种方法。它通过结构共享提供不可突变的,持久的集合

  1、不可突变:一旦创建,集合就不能在另一个时间点改变

  2、持久性:可以使用原始集合和一个突变来创建新的集合。原始集合在新集合创建后仍然可用

  3、结构共享:新集合尽可能多的使用原始集合的结构来创建,以便将复制操作降至最少从而提升性能

  不可突变数据使得变化跟踪很方便。每个变化都会导致产生一个新的对象,因此只需检查索引对象是否改变。例如,在这个常见的JavaScript代码中:

const x = { foo: 'bar' };
const y = x;
y.foo = 'baz';
x === y; // true

  虽然y被编辑了,但是由于它与x索引了相同的对象,这个比较会返回true。可以使用immutable.js实现类似效果:

const SomeRecord = Immutable.Record({ foo: null });
const x = new SomeRecord({ foo: 'bar' });
const y = x.set('foo', 'baz');
x === y; // false

  在这个例子中,x突变后返回了一个新的索引,因此我们可以安全的确认x被改变了

  还有两个库可以帮助我们使用不可突变数据:seamless-immutable 和immutability-helper。 实现shouldComponentUpdate时,不可突变的数据结构帮助我们轻松的追踪对象变化。这通常可以提供一个不错的性能提升

react性能优化的更多相关文章

  1. React性能优化记录(不定期更新)

    React性能优化记录(不定期更新) 1. 使用PureComponent代替Component 在新建组件的时候需要继承Component会用到以下代码 import React,{Componen ...

  2. 关于React性能优化

    这几天陆陆续续看了一些关于React性能优化的博客,大部分提到的都是React 15.3新加入的PureComponent ,通过使用这个类来减少React的重复渲染,从而提升页面的性能.使用过Rea ...

  3. React性能优化之PureComponent 和 memo使用分析

    前言 关于react性能优化,在react 16这个版本,官方推出fiber,在框架层面优化了react性能上面的问题.由于这个太过于庞大,我们今天围绕子自组件更新策略,从两个及其微小的方面来谈rea ...

  4. React 性能优化 All In One

    React 性能优化 All In One Use CSS Variables instead of React Context https://epicreact.dev/css-variables ...

  5. React 性能优化总结

    初学者对React可能满怀期待,觉得React可能完爆其它一切框架,甚至不切实际地认为React可能连原生的渲染都能完爆--对框架的狂热确实会出现这样的不切实际的期待.让我们来看看React的官方是怎 ...

  6. react 性能优化

    React 最基本的优化方式是使用PureRenderMixin,安装工具 npm i react-addons-pure-render-mixin --save,然后在组件中引用并使用 import ...

  7. React性能优化总结(转)

    原文链接: https://segmentfault.com/a/1190000007811296?utm_source=tuicool&utm_medium=referral 初学者对Rea ...

  8. react性能优化要点

    1.减少render方法的调用 1.1继承React.PureComponent(会自动在内部使用shouldComponentUpdate方法对state或props进行浅比较.)或在继承自Reac ...

  9. React性能优化总结

    本文主要对在React应用中可以采用的一些性能优化方式做一下总结整理 前言 目的 目前在工作中,大量的项目都是使用react来进行开展的,了解掌握下react的性能优化对项目的体验和可维护性都有很大的 ...

随机推荐

  1. Go开发之路 -- 函数详解

    声明语法 func 函数名 (参数列表) [(返回值列表)] {} Golang函数特点 a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变 ...

  2. java虚拟机的类加载器

    一.类的加载可以简单分成两种方式,静态加载和动态加载. 1.静态加载,就是new等方式使用到一个类的实例时,程序在运行到该处时,会把该类的.class文件加载到jvm里. 2.动态加载,通过Class ...

  3. TS学习随笔(七)->声明文件

    now我们来看一看TS怎么声明文件, 在JS里面我们经常会使用各种第三方类库,引入方式也不太相同,常见的就是在HTML中通过script标签引入,然后就可以使用全局变量$或者jQuery了 我们通常这 ...

  4. linux下的qt串口通信

    1.linux下的qt串口通信跟windows唯一的差别就是端口号的名字,windows下面是COM,而linux是ttyUSB0的路径 2.一般情况下linux插上USB转串口线就可以在/dev/目 ...

  5. DVWA 黑客攻防演练(七)Weak Session IDs

    用户访问服务器的时候,一般服务器都会分配一个身份证 session id 给用户,用于标识.用户拿到 session id 后就会保存到 cookies 上,之后只要拿着 cookies 再访问服务器 ...

  6. SpringMVC从认识到细化了解

    目录 SpringMVC的介绍 介绍: 执行流程 与strut2的对比 基本运行环境搭建 基础示例 控制器的编写 控制器创建方式: 请求映射问题: 获取请求提交的参数 通过域对象(request,re ...

  7. [20190415]关于shared latch(共享栓锁).txt

    [20190415]关于shared latch(共享栓锁).txt http://andreynikolaev.wordpress.com/2010/11/17/shared-latch-behav ...

  8. 在Visual Studio 2017上配置并使用OpenGL

    在Visual Studio 2017上配置并使用OpenGL 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 首先在Windows下安装Visual ...

  9. RabbitMQ广播:fanout模式

    一. 消息的广播需要exchange:exchange是一个转发器,其实把消息发给RabbitMQ里的exchange fanout: 所有bind到此exchange的queue都可以接收消息,广播 ...

  10. 打印进度条>>>>

    i+1: 当前的数量 300:  总数量 import sys print("下载中...") def process(curr, count): cursor_count = c ...