react 簡單優化

林尋丶發表於2018-02-06

在url後加 ?react_pref 可以結合Chrome自帶的Performance做效能測試

單元件優化:

核心:減少render函式執行次數

事件繫結:

  • 在constructor中使用bind繫結:
constructor(props) {
    super(props)
    this.eventHandle = this.eventHandle.bind(this)
}
複製程式碼
* 優點:只需要繫結一次,並且只會執行一次;
* 缺點:即使不需要state也需要新增constructor來繫結,程式碼量多一點
複製程式碼
  • 在render中使用bind繫結:
// ...
render() {
    return (
        <button onClick={this.clickHandle.bind(this)}></button>
    )
}
// ...
複製程式碼
* 優點:寫法簡單;
* 缺點:每次執行render都會重新執行一次,多次使用同一個函式需要繫結多次(不推薦使用該方法)
複製程式碼
  • 在render中使用箭頭函式繫結:
// ...
render() {
    return (
        <button onClick={() => this.clickHandle()}></button>
    )
}
// ...
複製程式碼
* 優點:寫法簡單,相對於上一種方法效能稍好一點;
* 缺點:每次執行render都要重新生成一個函式
複製程式碼
  • 在函式初始化時使用箭頭函式繫結(實驗性):
// ...
clickHandle = () => {
    // ...
}
render() {
    return (
        <button onClick={this.clickHandle}></button>
    )
}
// ...
複製程式碼
* 優點:寫法簡單,結合了以上三種方法的優點;
* 缺點:目前是實驗性的語法,需要babel轉譯
複製程式碼

總結:方式一是官方推薦的方式,也是效能最好的方式;方法二和方法三有效能問題,並且當方法作為屬性傳遞給子元件時會觸發re-render,因為子元件的props發生了改變;方法四是最好的繫結方式,但是需要結合babel轉譯

屬性傳遞:

由於js的特性(物件在記憶體中的儲存),如果傳遞的是一個物件,儘量提前宣告一個索引指向該物件,避免每次render都重新在記憶體中生成一個新的物件。

多元件優化:

核心:減少子元件render函式的執行次數(減少子元件的重渲)

定製子元件的shouldComponentUpdate

當父元件發生了render,子元件都會重新渲染。很多時候子元件並沒有發生任何改變,它接收到父元件傳給它的props並沒有發生變化,自身的state也沒有變化,這種情況下子元件的無腦重新render就可以在其shouldComponentUpdate()鉤子函式裡做一些操作。這個鉤子函式預設返回true,即render會執行;我們在裡面做些業務上的檢測,再返回true或false來確定子元件該不該重新渲染。

使用React.PureComponent(React@15.3新增)

它類似於React.Component,區別在於PurComponent簡單的實現了shouldComponentUpdate()而Component沒有實現。適用情況:元件的render函式在給定相同的props和state時渲染相同的結果(純元件),可以提升效能。

Note(官網上的Note) React.PureComponent’s shouldComponentUpdate() only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data. Furthermore, React.PureComponent’s shouldComponentUpdate() skips prop updates for the whole component subtree. Make sure all the children components are also “pure”.

PureComponent的shouldComponent()只實現了淺對比,深對比太消耗效能(物件的深比較需要用到遞迴,複雜度太高,效能消耗太大)。

可以使用immutable這個庫來進行物件的深比較,複雜度比較低,但是這個庫比較大。使用方法參考文件

redux優化

當我們頁面使用的資料需要對獲取的redux中的資料進行一些處理(複雜的計算)才能使用,並且很多狀態是經常切換得時候,我們可以將那些狀態快取起來,避免每次切換都重新計算。可以使用react官方推薦一個庫——reselect,使用方法參考文件

列表類元件優化

當我們渲染一個列表時,必須給每一項傳key,否則react會報一個警告。這個key不建議使用陣列遍歷時的index,因為它只能幫助我們消除警告而已,並沒有任何實際意義。如果我們在陣列前面新增一個元素,那麼react會認為所有的元素都發生了改變,所以全部都重新渲染了,我們並沒有感受到虛擬DOM帶給我們的優化。所以key的值必須是唯一的才有意義。


推薦閱讀
react元件效能優化探索實踐
高效能 React 元件

原文連結(linxunzyf.cn/posts/d5323…

相關文章