React性能优化之使用 ImmutableJS 不可变数据

众所周知,组件化是 React 的最大特性,因此咱们须要关注组件的优化。react

1、问题:不应从新渲染的子组件跟着别人又 render

咱们先来看一段包含子组件的代码:git

import React, { Component } from 'react';
import ColorShow from "./ColorShow";
class Example extends Component {
    constructor(props){
        super(props);
        
        this.state = {
            count:0
        }
    }
    btnClick = () => {
        this.setState({count:this.state.count+1})
    }
    render() { 
        return ( 
            <div> <h2>{`this is Immutable example , you click ${this.state.count} times`}</h2> <button onClick={this.btnClick}>click</button> <ColorShow /> </div>
         );
    } 
}
export default Example;
复制代码

子组件 ColorShow 的代码以下github

import React, { Component } from 'react';
class ColorShow extends Component {
    
    componentDidUpdate (){
        console.log("ColorShow componentDidUpdate");
    }
    render() { 
        return ( 
            <div > <h2>i am show area</h2> </div>
         );
    }
}
export default ColorShow;
复制代码

咱们在子组件 ColorShow 中的 componentDidUpdate 勾子里打印一些东西,代表在组件从新 render 了。运行以下dom

如动图可知,咱们其实只须要你点击几回的那块区域改变,可是子组件也每次都跟着从新渲染了。这就是咱们须要优化的性能问题了,咱们要它在该改变的时候,才去从新 render 的时候。

2、使用 PureComponent 优化

React15.3 增长 Component 的升级版 PureComponentPureComponent 不须要咱们去实现 shouldComponentUpdate 函数,它会浅比较的对比 prop 和 state 来决定组件是否须要 render。而浅比较的弊端是当 props 的结构比较复杂时,如多重对象嵌套,深层次对象的改变,这个浅比较就没法比较出来,从而阻止了组件的从新渲染。因此,PureComponent 并不能彻底帮助咱们在复杂数据时做出正确决策。函数

3、使用 Component 中的 shouldComponentUpdate 函数优化。

在组件中的 shouldComponentUpdate 函数返回 true 或 false,决定着组件是否从新 render,这就要对先后数据进行深度遍历比较,在数据的结构复杂时,这样很消耗性能。因此咱们使用不可变数据 Immutable,引入 Facebook 打造了三年的 immutable.js。如今,咱们来看下对比下深度遍历和不可变数据之间的性能比较。 咱们会随机生成数据,使用 lodash 中 isEqual 函数进行深度遍历,看代码组件化

//生成随机数据
let map = new Map();
for (let i = 0; i < 8000; i++) {
    map.set(Math.random(), Math.random());
}
let map1 = new Map();
for (let i = 0; i < 8000; i++) {
    map1.set(Math.random(), Math.random());
}

const _ = require("lodash");

//使用lodash进行深度遍历比较 map 和 map1
(function test () {
    console.time("isEqual");
    console.log(_.isEqual(map,map1));
    console.timeEnd("isEqual");
}());
复制代码

执行,比较程序的运行时间在 30ms 多。性能

接着咱们看看使用 immutable.js 库来比较的状况,先看代码

//生成随机数据
let map = new Map();
for (let i = 0; i < 8000; i++) {
    map.set(Math.random(), Math.random());
}
let map1 = new Map();
for (let i = 0; i < 8000; i++) {
    map1.set(Math.random(), Math.random());
}
const {is,fromJS} = require('immutable');

//生成不可变数据
const i_map = fromJS(map);
const i_map1 = fromJS(map1);

//使用immutable中的is函数 比较两个不可变数据 i_map 和 i_map1
(function test () {
    console.time("immutable_is");
    console.log(is(i_map,i_map1));
    console.timeEnd("immutable_is");
}());
复制代码

咱们先使用 fromJS 构建不可变数据,经过 is 函数比较。执行,函数执行时间在 3ms 左右。 优化

组件可以快速准确的作出是否从新渲染的决定,有利于提高咱们整个页面的性能。

4、总结

不可变数据 ImmutableReact 性能的优化,这彻底得益于 Immutable 的结构共享。咱们目前仅从组件的角度来体现,Immutable 还有更多更好的东西值得咱们研究和使用,好比和与 Redux 的搭配使用,具体你们能够参照阿里大佬camsong写的这篇详解ui

参考:
Immutable 详解及 React 中实践
immutable-jsthis

相关文章
相关标签/搜索