React组件性能优化总结

性能优化的思路

影响网页性能最大的因素是浏览器的重排(repaint)和重绘(reflow)。

React的Virtual DOM就是尽可能地减少浏览器的重排和重绘。

从React渲染过程来看,如何防止不必要的渲染是解决问题的关键。

性能优化的具体办法

1. 尽量多使用无状态函数构建组件

无状态组件只有props和context两个参数。它不存在state,没有生命周期方法,组件本身即有状态组件构建方法中的render方法。

在合适的情况下,都应该必须使用无状态组件。无状态组件不会像React.createClass和ES6 class会在调用时创建新实例,它创建时始终保持了一个实例,避免了不必要的检查和内存分配,做到了内部优化。

2. 拆分组件为子组件,对组件做更细粒度的控制

相关重要概念: 纯函数

纯函数的三大构成原则:

  • 给定相同的输入,它总是返回相同的输出: 比如反例有 Math.random(), New Date()
  • 过程没有副作用:即不能改变外部状态
  • 没有额外的状态依赖:即方法内部的状态都只能在方法的生命周期内存活,这意味着不能在方法内使用共享的变量。

纯函数非常方便进行方法级别的测试及重构,它可以让程序具有良好的扩展性及适应性。纯函数是函数式变成的基础。

React组件本身就是纯函数,即传入指定props得到一定的Virtual DOM,整个过程都是可预测的。

具体办法

拆分组件为子组件,对组件做更细粒度的控制。保持纯净状态,可以让方法或组件更加专注(focus),体积更小(small),更独立(independent),更具有复用性(reusability)和可测试性(testability)。

3. 运用PureRender,对变更做出最少的渲染

相关重要概念: PureRender

PureRender的Pure即是指满足纯函数的条件,即组件被相同的props和state渲染会得到相同的结果。

在React中实现PureRender需要重新实现shouldComponentUpdate生命周期方法。shouldComponentUpdate是一个特别的方法,它接收需要更新的props和state,其本质是用来进行正确的组件渲染。当其返回false的时候,不再向下执行生命周期方法;当其返回true时,继续向下执行。

组件在初始化过程中会渲染一个树状结构,当父节点props改变的时候,在理想情况下只需渲染一条链路上有关props改变的节点即可;但是,在默认情况下shouldComponentUpdate方法返回true,React会重新渲染所有的节点

有一些官方插件实现了对shouldComponentUpdate的重写,然后自己也可以做一些代码的优化来运用PureRender。

具体办法

(1) 运用PureRender

使用官方插件react-addons-pure-render-mixin实现对shouldComponentUpdate的重写

import React from ‘react‘;
import PureRenderMixin from ‘react-addons-pure-render-mixin‘;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }
  render() {
    return <div className={this.props.className}>foo</div>
  }
}

它的原理是对object(包括props和state)做浅比较,即引用比较,非值比较。比如只用关注props中每一个是否全等(如果是prop是一个对象那就是只比较了地址,地址一样就算是一样了),而不用深入比较。

(2)优化PureRender

避免无论如何都会触发shouldComponentUpdate返回true的代码写法。

避免直接为prop设置字面量的数组和对象

就算每次传入的数组或对象的值没有变,但它们的地址也发生了变化。

如以下写法每次渲染时style都是新对象都会触发shouldComponentUpdate为true:

<Account style={{color: ‘black‘}} />

改进办法:将字面量设置为一个引用:

const defaultStyle = {};
<Account style={this.props.style || defaultStyle} />
避免每次都绑定事件

如果这样绑定事件的话每次都要生成一个新的onChange属性的值:

render() {
  return <input onChange={this.handleChange.bind(this)} />
}

应该尽量在构造函数内进行绑定,如果绑定需要传参那么应该考虑抽象子组件或改变现有数据结构:

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
}
handleChange() {
  ...
}
render() {
  return <input onChange={this.handleChange} />
}
在设置子组件的时候要在父组件级别重写shouldComponentUpdate

4.运用immutable

JavaScript中对象一般是可变的,因为使用引用赋值,新的对象的改变将影响原始对象。为了解决这个问题是使用深拷贝或者浅拷贝,但这样做又造成了CPU和内存的浪费。

Immutable data很好地解决了这个问题。

Immutable data就是一旦创建,就不能再更改的数据。对Immutable对象进行修改、添加或删除操作,都会返回一个新的Immutable对象。Immutable实现的原理是持久化的数据结构。即使用旧数据创建新数据时,保证新旧数据同时可用且不变。同时为了避免深拷贝带来的性能损耗,Immutable使用了结构共享(structural sharing),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其他节点则进行共享。

原文地址:https://www.cnblogs.com/Bonnie3449/p/9642202.html

时间: 2024-10-07 13:48:14

React组件性能优化总结的相关文章

React组件性能优化

转自:https://segmentfault.com/a/1190000006100489 React: 一个用于构建用户界面的JAVASCRIPT库. React仅仅专注于UI层:它使用虚拟DOM技术,以保证它UI的高速渲染:它使用单向数据流,因此它数据绑定更加简单:那么它内部是如何保持简单高效的UI渲染呢? React不直接操作DOM,它在内存中维护一个快速响应的DOM描述,render方法返回一个DOM的描述,React能够计算出两个DOM描述的差异,然后更新浏览器中的DOM. 就是说R

React 组件性能优化探索实践

转自:http://www.tuicool.com/articles/Ar6Zruq React本身就非常关注性能,其提供的虚拟DOM搭配上Diff算法,实现对DOM操作最小粒度的改变也是非常的高效.然而其组件渲染机制,也决定了在对组件进行更新时还可以进行更细致的优化. react组件渲染 react的组件渲染分为初始化渲染和更新渲染. 在初始化渲染的时候会调用根组件下的所有组件的render方法进行渲染,如下图(绿色表示已渲染,这一层是没有问题的): 但是当我们要更新某个子组件的时候,如下图的

react中性能优化的点

react提升代码性能的点 1.绑定如果改变作用域点话放在constructor里面做,这样可以保证整个程序的作用域绑定操作只会执行一次,而且避免子组件的无谓渲染. 2.内置的setState是个异步操作,多次数据的改变变成一次,这样可以降低虚拟dom的比对频率 3.底层用虚拟dom,同层比对,key值等概念,来提升比对的速度,从而提升react的性能 4.借助shouldComponentUpdate,可以提高react的性能,因为可以避免无谓的组件render函数的运行. 原文地址:http

React.Component 与 React.PureComponent(React之性能优化)

前言 先说说 shouldComponentUpdate 提起React.PureComponent,我们还要从一个生命周期函数 shouldComponentUpdate 说起,从函数名字我们就能看出来,这个函数是用来控制组件是否应该被更新的. React.PureComponent 通过prop和state的浅对比来实现shouldComponentUpate(). 简单来说,这个生命周期函数返回一个布尔值. 如果返回true,那么当props或state改变的时候进行更新: 如果返回fal

React项目性能优化

1. 使用生产版本 确保发布的代码是生产模式下(压缩)打包的代码. 一般运行npm run build命令. 直接从webpack看配置文件,需要设置mode = 'production'. 调用teaser-webpack-plugin React Devtools可以根据地址栏右侧图标颜色判断是否是生产模式. 2.可视范围数据加载--虚拟化长列表 当网站需要加载大批量数据时,会加载特别慢.这个时候我们可以使用虚拟滚动插件,只渲染当前屏幕范围内的数据. 鼠标滚动去触发事件,再渲染一屏. 3.

react组件性能

一.渲染原理 二.性能优化 三.Immutable在性能优化中的作用 原文地址:https://www.cnblogs.com/94pm/p/9973317.html

如何对react进行性能优化

{...this.props} (不要滥用,请只传递component需要的props,传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担,因此,也请慎用spread attributes(<Component {...props} />)). ::this.handleChange().(请将方法的bind一律置于constructor) this.handleChange.bind(this,id) 复杂的页面不要在一个组件里面写完. 请尽量使

react+redux渲染性能优化原理

大家都知道,react的一个痛点就是非父子关系的组件之间的通信,其官方文档对此也并不避讳: For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillU

React 组件之 Component PureComponent Function Component

Virtual DOM , 通过高效的Diff算法对变化的部分首尾两端做批量更新,所有的比较都是浅比较shallowEqual.谁都玩不起深比较,facebook自己都做不到~ Component :一定要配套使用shouldComponentUpdate , 否则不管props or state是否更新组件一定更新 pureComponent :当组件的props和state不变时,组件是不更新的.仅仅只需要替换component => pureComponent,零投入超高回报 functi