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的复用上有两个判定条件:(具体了解可以参考:React 的调和算法

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值要保持唯一且稳定。

 

参考:  immutable Objects

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值