react元件有過哪些效能優化

2020-11-19 21:03:04

react的元件效能優化有:1、儘量多使用無狀態函數構建元件;2、拆分元件為子元件,對元件做更細粒度的控制;3、運用PureRender,對變更做出最少的渲染;4、運用immutable。

react的元件效能優化有:

1. 儘量多使用無狀態函數構建元件

無狀態元件只有props和context兩個引數。它不存在state,沒有生命週期方法,元件本身即有狀態元件構建方法中的render方法。

在合適的情況下,都應該必須使用無狀態元件。無狀態元件不會像React.createClass和ES6 class會在呼叫時建立新範例,它建立時始終保持了一個範例,避免了不必要的檢查和記憶體分配,做到了內部優化。

2. 拆分元件為子元件,對元件做更細粒度的控制

相關重要概念: 純函數

純函數的三大構成原則:

給定相同的輸入,它總是返回相同的輸出: 比如反例有 Math.random(), New Date()

過程沒有副作用:即不能改變外部狀態

沒有額外的狀態依賴:即方法內部的狀態都只能在方法的生命週期記憶體活,這意味著不能在方法內使用共用的變數。

純函數非常方便進行方法級別的測試及重構,它可以讓程式具有良好的擴充套件性及適應性。純函數是函數式變成的基礎。

React元件本身就是純函數,即傳入指定props得到一定的Virtual DOM,整個過程都是可預測的。

具體辦法

拆分元件為子元件,對元件做更細粒度的控制。保持純淨狀態,可以讓方法或元件更加專注(focus),體積更小(small),更獨立(independent),更具有複用性(reusability)和可測試性(testability)。

3. 運用PureRender,對變更做出最少的渲染

相關重要概念: PureRender

PureRender的Pure即是指滿足純函數的條件,即元件被相同的props和state渲染會得到相同的結果。

在React中實現PureRender需要重新實現shouldComponentUpdate生命週期方法。shouldComponentUpdate是一個特別的方法,它接收需要更新的props和state,其本質是用來進行正確的元件渲染。當其返回false的時候,不再向下執行生命週期方法;當其返回true時,繼續向下執行。

元件在初始化過程中會渲染一個樹狀結構,當父節點props改變的時候,在理想情況下只需渲染一條鏈路上有關props改變的節點即可;但是,在預設情況下shouldComponentUpdate方法返回true,React會重新渲染所有的節點。

有一些官方外掛實現了對shouldComponentUpdate的重寫,然後自己也可以做一些程式碼的優化來運用PureRender。

具體辦法

(1) 運用PureRender

使用官方外掛react-addons-pure-render-mixin實現對shouldComponentUpdate的重寫

import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
class App extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }
  render() {
    return <div className={this.props.className}>foo</div>
  }
}

它的原理是對object(包括props和state)做淺比較,即參照比較,非值比較。比如只用關注props中每一個是否全等(如果是prop是一個物件那就是隻比較了地址,地址一樣就算是一樣了),而不用深入比較。

(2)優化PureRender

避免無論如何都會觸發shouldComponentUpdate返回true的程式碼寫法。

避免直接為prop設定字面量的陣列和物件

就算每次傳入的陣列或物件的值沒有變,但它們的地址也發生了變化。

如以下寫法每次渲染時style都是新物件都會觸發shouldComponentUpdate為true:

<Account style={{color: 'black'}} />

改進辦法:將字面量設定為一個參照:

const defaultStyle = {};
<Account style={this.props.style || defaultStyle} />

避免每次都繫結事件

如果這樣繫結事件的話每次都要生成一個新的onChange屬性的值:

render() {
  return <input onChange={this.handleChange.bind(this)} />
}

應該儘量在建構函式內進行繫結,如果繫結需要傳參那麼應該考慮抽象子元件或改變現有資料結構:

constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
}
handleChange() {
  ...
}
render() {
  return <input onChange={this.handleChange} />
}

在設定子元件的時候要在父元件級別重寫shouldComponentUpdate

4.運用immutable

JavaScript中物件一般是可變的,因為使用參照賦值,新的物件的改變將影響原始物件。為了解決這個問題是使用深拷貝或者淺拷貝,但這樣做又造成了CPU和記憶體的浪費。

Immutable data很好地解決了這個問題。

Immutable data就是一旦建立,就不能再更改的資料。對Immutable物件進行修改、新增或刪除操作,都會返回一個新的Immutable物件。Immutable實現的原理是持久化的資料結構。即使用舊資料建立新資料時,保證新舊資料同時可用且不變。同時為了避免深拷貝帶來的效能損耗,Immutable使用了結構共用(structural sharing),即如果物件樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其他節點則進行共用。

相關學習推薦:

以上就是react元件有過哪些效能優化的詳細內容,更多請關注TW511.COM其它相關文章!