04-组件化高级-render性能优化

38 阅读2分钟

前言

渲染流程

  1. App根组件render函数通过jsx语法return了html标签元素,当然也可以包含react组件标签。
  2. render函数的运行实际上通过React.createElement('div', config, children)生成对应的reactComponent虚拟DOM
  3. 首次渲染,根据虚拟DOM生成真实DOM

渲染生命周期:

constructer->render->componentDidMount

更新生命周期:

(shouldComponentUpdate)->render->(beforeComponentUpdate)->componentDidUpdate

更新流程

  1. 触发更新的条件一定是: 组件内部的props或者state发生改变
  2. 接着render函数重新执行-》生成新的虚拟DOM树-〉新旧虚拟DOM进行diff->层级比较计算出差异进行更新-》更新到真实DOM image.png

更新中KEYS用法

image.png

render函数内性能优化

为什么需要render内性能优化?

假设有以下组件树结构

render () {
    console.log('App render')
    return (
      <div>
        <Home/>
        <Recommand />
      </div>
    )
  }

image.png

  • 当App根组件内出现setState或者props变化,不管改变的那个值是否在子组件中用到了,三个组件内部的render都会执行,App render-> Home render-> Recmannd render
  • 当APP内setState值和以前初始化的state值一样,也会造成三者render

这样做非常浪费性能,因为要重新生成虚拟DOM比对

解决方案

1、不太好的方案

SCU-shouldComponentUpdate

原理:

  • 组件的shouldComponentUpdate生命周期返回true 执行render,返回false 不执行render。
  • 该生命周期函数接受两个参数,nextProps,nextState,可根据即将更新的这2个值和当前state和props值比对,去判断return true/false

image.png 缺点:

  • 类组件能实现功能,但是当state中属性太多,会导致光内部逻辑判断非常多,对开发同学很不友好
  • 函数组件无法使用,因为没有生命周期

2、react实现的好方案

类组件 pureComponent

把类组件的继承由Component改为 PureComponent,这样内部自动实现了和外部数据不相干的组件不重新执行render

函数组件 memo

用memo包裹没有名字的函数,赋值给一个变量(即组件名字),并导出即可

image.png