簡測-react 性能 vs 原生js

閒來無事,想把之前一直想作的事驗證一下,react的性能到底怎樣?
和原生js相比呢?
下面老張從兩個方面進行簡單的測試
【數據渲染、數據更新】,
測試維度比較簡單、結果僅供參考,歡迎交流拍磚!
複製代碼

測試環境

mac i5 8g 、chrome 68.0.3440、react 16.2html

下面開始進行測試

測試1 數據渲染

渲染條數1w條,爲何是1w,數據量過小不容易看到差距,真實場景不會有這樣的場景,都是經過分頁展現不多的數據,因此得出的結果並不實際;node

react 代碼先行react

import './performence.less';
import React,{Component} from 'react';
import TestItem from './components/TestItem';//子組件

export default class Performance extends Component{
    constructor(props){
        super(props);
        this.state={
            page:'性能測試',
            itemArr:[],//要渲染的數據列表
        }
    }

   init={
       max:10000,//渲染的條數
       initMountTime:0//初始時間毫秒
   }

    //填充數據 ,更改數據
    componentDidMount=()=>{
        this.init.initMountTime=+new Date();
        let max=this.init.max;
        let i=0;
        let itemArr=this.state.itemArr;
        for(;i<max;i++){
            itemArr.push({
                title:'我是第'+i+'項'
            });
        }
        this.setState({
            itemArr:itemArr
        })
    }

    //每一條數據單機事件,改變當前的title
    itemClick=(index)=>{
        let oldArr=this.state.itemArr;
        oldArr[index].title="我被選中了------"+index;
        this.setState({
            itemArr:oldArr
        })
    }

    componentWillUpdate=()=>{
        this.init.initMountTime=+new Date();
    }

    componentDidUpdate=()=>{
        console.log(this.init.max,'條react渲染所需時間',(+new Date()) - this.init.initMountTime,'ms');
    }

    render(){
        return <main className="common-con-top">
                
            {this.state.itemArr.map((item, index) => <TestItem key={index} title={item.title} index={index} itemClick={this.itemClick}></TestItem>)}
             </main>
    }
}

//子組件
import React  from 'react';

export default class TestItem extends React.Component{
    constructor(props) {
        super(props);
    }

    render(){
        return <div onClick={this.props.itemClick.bind(this, this.props.index)} className="testItem"><span>{this.props.title}</span></div>
    }
}
複製代碼

原生代碼chrome

//也是基於react 進行編寫和初始化,只是數據項用原生渲染
 
import './performence1.less';
import React, { Component } from 'react';

export default class Performance1 extends Component {
    constructor(props) {
        super(props);
        this.state = {
            page: '性能測試',
            itemArr: []
        }
    }

    init = {
        max: 10000,
        initMountTime: 0 
    }
    //原生js生成數據項
    componentDidMount = () => {
        this.init.initMountTime = +new Date();
        let max = this.init.max;
        let i = 0;
        let html='';
        for (; i < max; i++) {
            html +='<div class="testItem"><span>我是第'+i+'項</span></div>'
        }
      
        document.getElementById('div_demo_id').innerHTML=html;
        console.log(this.init.max, '條原生渲染所需時間', (+new Date()) - this.init.initMountTime,'ms');
    }
    componentWillUpdate = () => {

    }

    componentDidUpdate = () => {
    }


    render() {
        return  <div id="div_demo_id"></div>
    }
}
複製代碼

請看測試結果bash

這個測試結果看似差距很大,可是實際狀況不會有直接渲染1w條的狀況,若是將數據量再縮小後,差距也存在,可是性能是能夠接受的!less

測試2 更新數據

點擊其中一條數據後標題改變,我們來看看執行須要多長時間,仍是基於1w的數據dom

react 事件處理代碼 以及 用時計算組件化

itemClick=(index)=>{
        let oldArr=this.state.itemArr;
        oldArr[index].title="我被選中了------"+index;
        //oldArr.splice(index,1);
        this.setState({
            itemArr:oldArr
        })
    }
    componentWillUpdate=()=>{
        this.init.initMountTime=+new Date();
    }

    componentDidUpdate=()=>{
        console.log(this.init.max,'條react渲染所需時間',(+new Date()) - this.init.initMountTime,'ms');
    }
複製代碼

原生事件處理性能

componentDidMount = () => {
        this.init.initMountTime = +new Date();
        let max = this.init.max;
        let i = 0;
        let html='';
        for (; i < max; i++) {
            html +='<div dataindex="'+i+'" class="testItem">我是第'+i+'項</div>'
        }
      
        document.getElementById('div_demo_id').innerHTML=html;
        console.log(this.init.max, '條原生渲染所需時間', (+new Date()) - this.init.initMountTime,'ms');
        
        document.getElementById('div_demo_id').addEventListener('click',(e)=>{
            if (e.target.nodeName === 'DIV'){
                e.target.innerHTML='我被選中了----'+e.target.getAttribute('dataindex')
            }
        });
    }
複製代碼

react 執行結果測試

原生的處理時間我沒貼,由於使用的是事件代理 直接修改的當前的節點,耗時能夠忽略不計了;

react的這個耗時貌似有點高,那有沒有能夠優化的手段呢? react其實已經提供了,那就是shouldComponentUpdate

看代碼

// 在子組件內部增長一個方法 剛纔我們修改的是標題,那就經過標題來進行處理
 shouldComponentUpdate(nextProps,nextState){
        if(nextProps.title!==this.props.title){
            return true;
        }
        return false;
    }
// 下面在看下測試結果
複製代碼

進行簡單的優化後性能有所提高,提高了50-70ms ,這也是我什麼要提取一個子組件出來;

我的結論 經過上面的兩個簡單的測試,發現react性能和原生性能存在必定的差距,同時react提供咱們能夠優化的空間,react給到的是相對差很少的性能,並非說虛擬dom比原生的快,只是react的組件化思想是一種全新得突破,讓咱們儘量的少的操做dom,不用過多的考慮性能問題也能開發出性能差很少,過的去的應用;

僅供參考,歡迎交流和指正。

相關文章
相關標籤/搜索