React:性能优化

减少子组件重复渲染:

getDerivedStateFromProps

当父组件重新渲染,不论传入当前组件的props是否发生变化,其getDerivedStateFromProps都会被执行,这将导致不必要的重复渲染。

当组件setState执行后,其getDerivedStateFromProps也都会被执行。

组件的getDerivedStateFromProps方法应用于组件state仅根据传入props变更进行更新的场景。

对于表单,通过使表单控件成为完全受控组件,props和onChange由父组件传入,子组件不维护state,或使表单控件成为完全不受控组件,只从父组件获取初始props,子组件通过setState维护state,通过变更子组件key重置state,两种方式可以避免getDerivedStateFromProps。

shouldComponentUpdate

在上面情形中,当getDerivedStateFromProps被执行后,会继续React组件生命周期,故shouldComponentUpdate也都会被执行。

通过shouldComponentUpdate对新老props(或新老state)进行比对,判断是否发生变化,返回比对结果,可以避免由此造成的子组件重复渲染。

PureComponent

React在PureComponent组件中封装了通过shouldComponentUpdate进行新老props和(或新老state)比对的更新策略,当父组件更新与当前组件无关时,则不会触发当前组件更新,并跳过当前组件的整个子组件树(故子组件也应是PureComponent或静态组件)。

需要注意的是,PureComponent组件仅仅是通过shouldComponentUpdate对props和state进行了浅比较,对于props或state数据的层级不是扁平结构时将不会对更深层级数据变化进行比对。

如果state和prosp不可避免使用深层数据,可以通过使用不可变对象提升深层数据比较速度。

对于state深层更新,还可以通过更新时直接对深层数据使用新对象来触发组件渲染。

如果能够确切知道某些深层数据发生变化,则可以调用component.forceUpdate方法跳过比较直接进行强制更新。

memo

对于函数组件,可以使用React.memo方法对组件进行封装,React.memo本身是一个HOC,传入函数组件和更新判断方法,实现类似类组件中shouldComponentUpdate方法的功能,更新判断方法为可选参数,为空时默认对props进行浅比较,否则按照更新判断方法进行数据比对。

与PureComponent不同的是React.memo仅对props进行比对,不比对state。

与shouldComponentUpdate不同的是React.memo的更新判断方法返回true时为不更新,而shouldComponentUpdate则相反。

需要注意的是,React.memo应作为性能优化手段而不是渲染控制逻辑来使用。

setState机制:

当调用组件setState方法后,React会进行虚拟DOM更新、合成更新、diff算法比对,经过以下四个生命周期:

  • getDerivedStateFromProps
  • shouleComponentUpdate
  • render
  • componentDidUpdate

由React触发的setState每次执行时都会进行合成更新,因此由React绑定的事件处理函数(如onClick、onChange等)、生命周期函数中调用setState,都时异步执行的;不经过React控制、直接触发(如原生DOM绑定的事件处理函数、setTimeout/setInterval、Promise回调函数等)的setState会同步执行。

由于setState的异步执行机制,当多次调用setState方法时,应传入更新回调方法进行更新,而不是直接使用this.state值ÿ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值