react 性能提升

使用React框架时,可以从两方面提高应用的性能:

  • 减少不必要的Render函数的调用。
  • 复用Dom

减少不必要的Render函数的调用

在React的生命周期里有四种方式可以触发一个组件render函数的调用,分别是:

1. 组件初始挂载时

2. props 更新时

3. 调用 setState()

4. 调用forceUpdate()

这四种方式中,初始挂载的调用是必不可少的,setState() 时的调用React 已经做了优化,会合并多次处理,forceUpdate()时的调用是应用方主导发起,只有props的更新导致的调用并不是全部有必要的,例如父组件重新渲染,但是子组件的props并未变化,也会触发子组件的render函数调用。

对于statefull的class 类型的组件

可以从两个方法优化:

1. 使用PureComponent取代Component,因为PureComponent 重新定义了shouldComponentUpdate 钩子函数,会对newProps和Props 的属性作浅比较,属性都没有变化时,会返回false,不会再调用render函数,组件的更新流程终止。而Component内定义的shouldComponentUpdate默认是永远返回true。

2.组件内重写shouldComponentUpdate钩子函数,比较newProps和Props,只有属性值发生变化,才返回true。

为了降低newProps 和Props的diff 成本,对props的属性要使用imutable objects,这样可以直接浅比较,就能识别属性有无变化,不需要进行深层次的比较,减少diff 时间复杂度。这就要求父组件在修改state时,不要直接修改Object 和 Array类型数据的值,而是生成新的地址。

例如:父组件的dataList 要增加一个元素“text”,如果直接用push方法,dataList 地址不会变化,子组件的shouldComponentUpdate函数对newProps和props进行浅比较是发现不了变化的。

const {dataList} = this.state;
 
dataList.push("test"); // dataList 是 mutable的,浅比较无法识别变化
 
this.setState({dataList})

将dataList改为immutable的,使用concat 生成新的dataList。

const {dataList} = this.state;
 
const newDataList = dataList.contat(["test"]); // dataList 是 immutable的,创建新的数组,浅比较可直接判定出变化
 
this.setState({dataList:newDataList})

对于stateless的function component

class类型的组件可以通过比较newProps和props来减少不必要的渲染,那对于函数式组件,有没有类似的方式呢?有的,React 也设计了一个memo方法,实现相同的功能。官网对React.memo的解释如下:

“React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of classes.”

React.memo 返回的是一个高阶组件,他的功能和React.PureComponent 一致,减少组件因为不必要的props变化引起的渲染。只是React.memo是作用在函数式组件上的。

memo方法接受两个参数,第一个参数是组件函数,第二个参数是props diff 函数。memo内部默认会浅比较newProps和Props的属性,发生变化时,才执行组件重渲染。我们也可以用第二个参数改变diff方法。

复用Dom

react 在Dom的复用上有两个判定条件:

1. type 相同

2. key 值相同

为减少Dom的创建,在更新时,尽量保持节点的type不变,例如:total属性大于2时,节点由div 变为 span,这样会引起不必要的Dom创建。

function Counter({total}){
    return total > 2? <div>计数达到上线</div>: <span>计数没有达到上线<span>    
}

为减少Dom不必要的创建和更新,要合理的使用key。对于单节点,不要滥用key(特殊:对于逻辑复杂的组件,更新成本高于创建时,在单节点上使用key,也可以提高性能)。 对于数组节点,key值要保持唯一且稳定。 

 

posted @ 2021-12-29 11:20  秋墨江雪  阅读(57)  评论(0编辑  收藏  举报