美文网首页react
React性能优化(1)

React性能优化(1)

作者: 梭子蟹_3984 | 来源:发表于2018-03-06 18:55 被阅读41次

React是一个专注UI层的框架,它使用虚拟DOM技术,以保证它UI的告诉喧染;使用单向数据流,因此它的数据绑定更加的简单;那么它内部是如何保持简单高效的UI渲染呢?这种渲染机制有可能存在什么性能问题呢?

React组件渲染问题引出

React不直接操作DOM,它在内存中维护一个快速相应的DOM描述,render方法返回一个DOM的描述,React能够计算出两个DOM描述的差异,然后更新浏览器中的DOM。这就是著名的DOM Diff.

也就是说React在接受属性(props)或者状态(state)更新时,就会通过前面的方式更新UI。所以React整个UI喧染是比较快的,但是这里面可能出现的问题是:
假设我们定义一个父组件,其包含了5000个子组件。我们有一个输入框输入操作,每次输入一个数字,对应的那个子组件的背景变红。

<Components>
  <Components-1 />
  <Components-2 />
  <Components-3 />
  ...
  <Components-5000 />
</Components>

这样我们在输入数字1,则子组件1的背景色变化,但是在这个过程中,所有的子组件都进行了重新渲染,导致整体渲染变慢,造成这种现象的原因是React中父组件更新默认出发所有子组件更新。
同时,我们经常在便利列表元素的时候会遇到这样的提示:

Warning: Each child in an array or iterator should have a unique "key" prop.

这就是我们要探讨的两个性能优化点:

  • 1.父组件更新默认触发子组件更新
  • 2.列表类型的组件默认更新方式非常复杂

React性能检测工具

我们利用react-addons-pref进行性能检测。引入的方式如下:

import Perf from 'react-addons-perf'
window.Perf = Perf // 挂载到全局变量方便使用

检测方法,在浏览器控制台中输入如下命令:

  • 开始记录:Perf.start()
  • 结束记录:Perf.stop()
  • 打印结果:printInclusive()
1491542236024.png

控制台会以表格的形式展示出结果:

1491542600197.png

上图记录了每个组件的执行耗时,渲染次数等关键信息。我们可以有针对性的进行优化。

注意:生产环境不要引入Perf

React性能优化原理

这是React官网对组件渲染机制的描述图,其中绿色组件代表不需要更新,红色组件需要更新,影响更新的条件主要有SCU(shouldComponentUpdate)及DOM DIff结果。

1491537026005.png

我们再来看看 组件触发更新的流程图:

render.png

通过上述的流程图,再对比喧染的图解可以看到,React的性能瓶颈主要出现在DOM以及DOM Diff的过程。如果进行性能优化,关键在于:

  • shouldComponentUpdata 阶段判断,如果属性及状态与上一次相同,这个时候很明显UI不会变化,也不需要执行后续生成DOM,DOM Diff的过程了,可以提高性能。
  • DOM Diff 阶段优化,提高Diff的效率

如何提高组件的渲染效率

针对文章开头提出的两个性能问题,我们得到以下解决方案:

  • 子组件执行 shouldComponentUpdate 方法,自行决定是否更新
  • 给列表中的组件添加key属性

我们可以控制子组件的shouldComponentUpdate从而控制是否渲染:

shouldComponentUpdate(nextProps, nextState) {
    // 如果当前的value值与待更新不相等,才执行更新
    return this.props.value !== nextProps.value;
}

针对列表遍历类型,遍历的时候添加唯一key属性,对子组件进行唯一识别,准确知道要操作的子组件,提高DOM Diff的效率。

array.map(val, index) => {
   return <span key={index}>{val}</span>
})

PureRenderMixin与PureComponent

为了提高React组件喧染性能,React针对组件的shouldComponentUpdate方法进行了封装处理,我们不需要在每个组件里面手动编写shouldComponentUpdate。

PureRenderMixin

React在之前版本提供了 PureRenderMixin 的mixin形式,其用法如下:

// react官方demo
import PureRenderMixin from 'react-addons-pure-render-mixin';
class FooComponent extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }

其原理就是重写了 shouldComponentUpdate 方法。

PureComponent

React 15.3.0 新增了一个 PureComponent 类,以 ES2015 class 的方式方便地定义纯组件 (pure component),用于取代之前的 PureRenderMixin。

这个类的用法很简单,如果你有些组件是纯组件,那么把继承类从 Component 换成 PureComponent 即可。当组件更新时,如果组件的 props 和 state 都没发生改变,render 方法就不会触发,省去 Virtual DOM 的生成和比对过程,达到提升性能的目的。

import React, { PureComponent } from 'react'

class Example extends PureComponent {
  render() {
    // ...
  }
}

这里要注意的是:PureRenderMixin、PureComponent 内进行的仅仅是浅比较对象(shallowCompare)。如果对象包含了复杂的数据结构,深层次的差异可能会产生误判。比如,如果我们的state变为:

state = {
     value: { foo: 'bar' }
}

// 每次更改value值的时候进行:
this.setState({ value: newValue });

此时直接通过值的比较是行不通的,因为对象的引用关系,导致在子组件里面接受到的 this.props.value 与 nextProps.value 永远都是相等的。这里的解决方案主要有:

  • 深比较: 原理与深拷贝类似,比较耗时,不推荐
  • immutable.js:FaceBook官方提出的不可变数据解决方案,主要解决了复杂数据在deepClone和对比过程中性能损耗

总结

虽然React提供了Virtual DOM DOM Diff 等优秀的能力来提高渲染性能,但是在实际使用过程中,我们经常会遇到父组件更新,不需要更新所以子组件的场景(分页),此时必须考虑利用React本周的渲染机制来进行优化。

相关文章

  • 【React.js 20】React性能优化

    React性能优化 React性能优化主要分三块: React 组件性能优化 属性传递优化针对单组件性能优化,很多...

  • 深入浅出React和Redux学习笔记(五)

    React组建的性能优化 性能优化的方法: 单个React组件的性能优化; 多个React组件的性能优化; 利用r...

  • react 框架性能优化

    react 框架性能优化 前端性能监控利器 1.Google Performance工具 2.react 性能查看...

  • Redux源码剖析

    前面写了《React组件性能优化》《Redux性能优化》《React-Redux性能优化》,但是都没有从这些框架的...

  • react性能优化

    React 性能优化 React 性能优化 | 包括原理、技巧、Demo、工具使用[https://juejin....

  • React-Redux性能优化

    前面写了两篇文章《React组件性能优化》《Redux性能优化》,分别针对React和Redux在使用上的性能优化...

  • react-native性能优化的考虑

    性能优化的学习 React Component的性能考虑 1 createClass 和 extends Reac...

  • React 性能优化

    React 性能优化 简单的 todo-list-demo 讲 React 性能优化不能光靠嘴说,得有一个 dem...

  • React性能优化方案

    React 性能优化 简单的 todo-list-demo 讲 React 性能优化不能光靠嘴说,得有一个 dem...

  • React 组件性能优化

    React 组件性能优化最佳实践 React 组件性能优化的核心是减少渲染真实 DOM 节点的频率,减少 Virt...

网友评论

    本文标题:React性能优化(1)

    本文链接:https://www.haomeiwen.com/subject/xdurfftx.html