React PureComponent and Performance

React在15.3.0新增了PureComponent的類別,我們基本上可以直接無痛從extends Component轉到extends PureComponent
大部分情況下直接使用PureComponent會是較方便的做法,省去了自己寫shouldComponentUpdate (自己寫的話還會報錯)
但也不代表用了PureComponent整個效能就會提升,根本的療法還是要將Component寫的pure-render,意指假如傳給Component的prop & state都是一樣,那vDOM回傳的結果也該是一樣

Non-pure

最常見的non-pure寫法就像是以下

1
2
3
4
5
6
7
// 每次render傳進去的都是新的Object
<Button style={{color: 'red'}} />
<Children data={{x: 1, y: 2}} />
// inline-function, 每次render傳進去的都是新的Function
<Button2 onClick={e => console.log(e)} />

這樣的inline寫法,雖然會造成每次一有變動,每個Children Component都會去檢查一次,很多東西要檢查「理論上」耗費的時間也會變多,但我們真的就該改掉這樣的寫法嗎?這篇文章給了我們些值得探討的問題,程式變慢真的是這些non-pure造成的嗎?

實驗

我在Github上開了一個用來實作PureComponent的專案,有興趣的人也可以直接到打開log看看
其中的一個結論是

當傳給Children Component的props「是」pure,更新children會觸發children的ComponentDidUpdate & render,但畫面上不會有任何改變,真的被skip掉了;而Parent Component的更新,並不會觸發children的ComponentDidUpdate & render

結語

「不要過早開始優化」,這是文章中作者很強調的一點,當你要做優化時,要好好做實測;是inline-style造成的嗎?還是有更大的問題在Code裡?
優化沒辦法一次到位,從使用的過程中逐漸察覺出可加強的部分,首要關注的還是專案本身的產出
官方也有建議到,因PureComponent做的是shallow compare,所以較複雜的data structures可以用immutable objects來加快比對速度(ex. Immutable.js)

Reference

React, Inline Functions, and Performance
React PureComponent 源码解析
我的實驗

0%