React Redux使用的一些小優化

Clark發表於2017-01-20

之前畫了一張redux的流程圖,可以看看右下角的部分,可以看出來怎麼進行優化。

在reducer裡面,儘量減少資料的變動

不要做多餘、無意義的事

也就是能不改變就不改變。比如不要做下面這種無謂的事情:

function reducer(state, action){
  // ....一大堆邏輯程式碼
  return {
   ...state
  }
}

這個程式碼雖然在selector中,也可以通過areStatePropsEqual來判斷計算後的state是否發生了改變。

但是如果直接return state;就可以直接被areStatesEqual攔截,避免多餘的計算和對比。

要做多餘的檢查

同樣,state內部資料,如果資料相同,儘量使用原資料。只針對複雜資料型別(Object, Array)。
比如:

function reducer(state, action) {
  let mayNotChange = state.mayNotChange; // mayNotChange為Array或Object
  let newState = {...mayNotChange};
  // ...一大堆邏輯
  return {
    ...state,
    mayNotChange: changed ? newState : mayNotChange // 沒有發生改變的話,就用原來的物件
  }
}

很多時候,一般習慣於通過計算,然後直接把生成的newState賦值給mayNotChange

由於眾所周知的{} !== {}的情況,如果能通過簡單判斷來決定是否可以選擇使用原來的物件,那麼就可以通過areStatePropsEqual來進行判斷,同樣可以避免不必要的計算,更可以避免不必要的渲染。

注: 所說的選擇使用原來的物件,是確定資料沒有發生改變的時候,使用原物件。並不是說當發生改變的時候,也在原來的物件上面修改最好。在不考慮自定義areStatesEqual和areStatePropsEqual的情況下,如果只在原物件上面進行修改,可能會造成對比的時候,前後兩種結果相同,可能造成無法重新渲染的情況

優化equal的四個方法

connectoption中,有四個對比的方法

  1. areStatesEqual(預設為===),用來判斷redux store返回的state是否和之前的相同

  2. areOwnPropsEqual(預設為shallowEqual),用來判斷父元件傳入的props是否和之前的相同

  3. areStatePropsEqual(預設為shallowEqual),用來判斷mapStateToProps的結果是否和之前的相同

  4. areMergedPropsEqual(預設為shallowEqual),用來判斷最後merge合併的最終結果是否和之前的相同

可以通過自己的需求對著四個方法進行優化。


比如一個reduxstate是這個樣子:

  state = {
    pageA: {...},
    pageB: {...},
    number: 2
  }

而在pageA裡面只需要pageAnumber,那麼就可以通過areStatesEqual來進行對比:

function areStatesEqual(prev, current){
  return prev.number === current.number && isEqual(prev.pageA, current.pageA);
}

或者針對複雜結構資料的情況,進行特殊處理,比如深度對比

function areStatePropsEqual(prev, current){
  return deepEqual(prev, current);
}

這些優化都可以減少不必要的計算和重渲染。

shouldComponentUpdate

多餘提一句,在使用shouldComponentUpdate的時候,要謹慎使用。這個方法就是利用shouldComponentUpdate的消耗來換取render的消耗。

當某些小的、呼叫的次數少的component,就沒有必要新增shouldComponentUpdate檢查。

當元件夠大,夠複雜,可以考慮使用這個方法來減少re-render的消耗。當然,還是需要考慮用這個方法的消耗和diff&render的消耗比起來哪個更划算。



先想到這麼多,等想到了其他的再新增上來。

相關文章