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

相關文章
相關標籤/搜索