高德納: "我們應該忘記忽略很小的性能優化,可以說97%的情況下,過早的優化是萬惡之源,而我們應該關心對性能影響最關鍵的另外3%的代碼。"
不要將性能優化的精力浪費在對整體性能提高不大的代碼上,而對性能有關鍵影響的部分,優化并不嫌早。因為,對性能影響最關鍵的部分,往往涉及解決方案核心,決定整體的架構,將來要改變的時候牽扯更大。
1. 單個React組件的性能優化
React利用Virtual DOM來提升渲染性能,雖然每一次頁面更新都是最組件的從新渲染,但是并不是將之前的渲染內容全部拋棄重來,借助Virtual DOM,React能夠計算出對DOM樹的最少修改,這就是React默認情況下渲染都很迅速的秘訣;
不過,雖然Virtual DOM能夠將每次DOM操作量減少到最小,但,計算和比較Virtual DOM依然是一個復雜的過程;
當然,如果能夠在開始計算Virtual DOM之前就判斷渲染的結果不會有變化,那么就可以不進行Virtual DOM計算和比較,速度就會更快。
2.shouldComponentUpdate的默認實現方式
既然可以對組件在開始計算Virtual DOM之前判斷渲染結果不會有變化時,阻止渲染的進行,從而提升性能,那么我們自然想到使用shouldComponentUpdate(nextProp,nextState)
shouldComponentUpdate函數在render函數之前調用,決定“什么時候不需要從新渲染”;
即返回一個布爾值,決定更新是否進行下去,默認返回true,若返回false則中斷更新;
shouldComponentUpdate(nextProp,nextState){ return (nextProp.completed !== this.props.completed) || (nextProp.text !== this.props.text)}其中nextProps為此次更新傳入的props,對于這個組件,影響渲染內容的prop只有completed和text,只要確保這兩個prop沒有變化,shouldComponentUpdate就可以返回false阻止沒必要的更新
但是,上述的比較只是‘淺層比較',如果類型是基本類型,只要值相同,那么“淺層比較”
也會認為二者相同:
那,如果prop的類型是復雜的對象怎么辦?
對于復雜對象,‘淺層比較'的方式只看這兩個prop是不是同一個對象的引用,如果不是,哪怕對象中的內容完全一樣也會認為是不同的兩個prop。那么使用“深層比較”:但對對象的結構是無法預知的,如果遞歸對每個字段都進行“深層比較”,不光會讓代碼更加復雜,也可能會造成性能問題。
所以,要想判斷前后的對象類型的prop是相同的,就必須要保證prop是指向同一個JavaScript對象:
<Foo styleProp = {{color: "red"}}>要避免使用上面的傳入方式,應為每次渲染都會重新創建{color: "red"}對象,引用地址每次都不同,將導致每次的styleProp都不同。
新聞熱點
疑難解答
圖片精選