八、React性能优化、更新机制、SCU优化、shouldComponentUpdate

315 阅读1分钟

更新机制

graph TD
JSX --> 虚拟DOM --> 真实DOM

props或state发生改变->render函数被重新执行->产生新的虚拟DOM->新旧DOM进行diff算法->差异更新->更新真实DOM

  • 同层节点比较
  • 对于不同类型的节点进行直接替换、不会比较子节点
  • 列表循环绑定key的diff算法优化

render函数优化

存在问题:setState发生改变会重新执行render函数、即使我只是改了一个初始值、内部的子组件并未发生改变也会重新执行、进行一个整体上的重新渲染。即App组件的render函数重新执行、内部子组件的render函数都会被重新执行一次浪费性能

// SCU优化
// 需要对传入的props有没有改变 or 自己的state前后值有没有变化
shouldComponentUpdate(nextProps, nextState) {
    if (this.state.msg !== nextState.msg || this.props.counter !== nextProps.counter) {
      return true; // render函数会被重新执行
    }
    return false;
}

SCU优化

PureComponent

目的:就是为了监听传入的属性和状态state是否有变化,是否需要重新执行render函数提高性能,做的浅能比较

import React, { Component, PureComponent } from "react";

export class App extends Component {}

// 继承PureComponent就实现了性能优化
export class App extends PureComponent {}

// 这个是错误的 PureComponent
this.state.movie.push('海贼王')
this.setState({movie: this.state.movie})

// 正确做法
const movies = [...this.state.movie]
movies.push('一条数据')
this.setState({movie: movies})

memo

目的:类组件可以使用PureComponent进行优化,这样只有组件所依赖的props和state发生改变的时候,rander函数才会被重新执行。而在函数组件里面采用memo包裹

import {memo} from 'react

function Home(props) {
    return (
        <div>{props.msg}</div>
    )
}

// 不包裹的时候只要App组件数据发生变化 整体的render函数就需要重新执行 即使我们没有改变msg的值 浪费性能

const Home = memo(function(props) {
    return (
        <div>{props.msg}</div>
    )
})

export default Home