通過PureRender和Immutable實現React中的效能優化
簡要介紹:React中的render存在著不必要的渲染,可以通過Puer Render(PureComponent)來減少渲染的次數,但是Puer Render只是進行淺比較,無法實現深層物件上的效能優化。Pure Render結合Immutable可以減少渲染次數。
1 . React中的render
僅通過React中的render,存在著不必要的渲染,這種不必要的渲染分為兩大類。
(1)自身的state沒有改變
在React的render中,只要發生setState行為,就會去重新渲染,即使setState的屬性前後並沒有發生變化,比如:
class TestComponent extends React.Component{
constructor(props){
super(props);
this.state={
count:0
}
}
componentDidMount(){
let self=this;
setTimeout(function(){
self.setState({
count:0
})
},1000)
}
componentDidUpdate(){
console.log(`元件更新了`);
}
render(){
return <div>1</div>
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
在這個元件中,我們setState的值在前後並沒有發生改變,但是呼叫此元件會輸出:
//元件更新了
- 1
說明只要setState發生了,即使值在前後沒有發生變化,元件也會重新render。
(2)父元件傳遞的props會引起所有子元件render
父元件中的值傳遞給子元件,即使某些子元件中不需要重新渲染,也會重新render。舉例來說,父元件為Father:
class Father extends React.Component{
constructor(props){
super(props);
this.state={
obj:{
title:`test immutable`,
childZero:{
name:`childZero`,
age:0
},
childOne:{
name:`childOne`,
age:1
},
childTwo:{
name:`childTwo`,
age:2
}
}
}
}
componentDidMount(){
let self=this;
let {obj}=this.state;
setTimeout(function(){
self.setState({
obj:obj
})
},1000)
}
render(){
const {obj}=this.state;
return <div>
<ChildZero obj={obj}/>
<ChildOne obj={obj}/>
<ChildTwo obj={obj}/>
</div>
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
父元件有3個子元件:
class ChildZero extends React.Component{
constructor(props){
super(props);
}
componentDidUpdate(){
console.log(`childZero觸發了更新`)
}
render(){
return <div>3</div>
}
}
class ChildOne extends React.Component{
constructor(props){
super(props);
}
componentDidUpdate(){
console.log(`childOne觸發了更新`)
}
render(){
return <div>3</div>
}
}
class ChildTwo extends React.Component{
constructor(props){
super(props);
}
componentDidUpdate(){
console.log(`childTwo觸發了更新`)
}
render(){
return <div>3</div>
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
我們在父元件的componentDidMout方法中,setState然後觀察子元件的更新情況,發現所有的子元件都會更新,具體輸出為:
//childZero觸發了更新
//childOne觸發了更新
//childTwo觸發了更新
- 1
- 2
- 3
2 . Pure Render可以減少淺層物件上不必要的更新
通過定義元件為Pure Render可以通過淺層比較,減少不必要的更新。我們通過使用PureComponent。同樣的我們以1(1)中的為例:
class TestComponent extends React.PureComponent{
constructor(props){
super(props);
this.state={
count:0
}
}
componentDidMount(){
let self=this;
setTimeout(function(){
self.setState({
count:0
})
},1000)
}
componentDidUpdate(){
console.log(`元件更新了`);
}
render(){
return <div>1</div>
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
通過PureComponent來代替Component,此時如果僅僅是淺層物件屬性,當setState前後屬性不變時,那麼就不會有不必要的渲染。但是對於深層物件而言,pure Render無法實現。
3 .通過Immutable實現深層物件的效能優化
Immutable實現了js中的不可變資料結構,immutable具有不可變性,永續性等特點,通過資料共享的方式,修改相應的屬性實現深度克隆的過程只會影響父類屬性。
通過immutablejs可以方便進行深層物件的“相等”判斷。在React的效能優化中,在生命週期函式shouldComponetUpdate中判斷在是否需要更新,進行前後props和前後state的深層比較。
shouldComponentUpdate(nextProps,nextState){
//進行深層判斷使用immutable
const thisProps=this.props;
if(Object.keys(thisProps).length!==Object.keys(nextProps).length){
return true;
}
for(const key in nextProps){
console.log(is(thisProps[key],nextProps[key]));
if(!is(thisProps[key],nextProps[key])){
return true;
}
}
return false;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
如果返回true,那麼會進行render,如果返回false,就不會render,從而可以控制深層物件是否需要重新render,實現了效能的優化。
這裡使用immutable,主要是因為其擁有如下特點:
I)快,在深層對比物件(Map)或者陣列(List)是否相同,比深層克隆式的比較快
II)安全,指的是對所有immutable的增刪改查,都是增量,不會使得原始資料丟失
3.immutable的缺點
使用immutalbe也存在了一些缺點:
(1)immutablejs原始檔較大
(2)具有很強的侵入性
相關文章
- Redux + Immutable.js 效能優化ReduxJS優化
- 通過自動化和現代化實現網路優化優化
- Immutable 操作在 React 中的實踐React
- [譯] 拖放庫中 React 效能的優化React優化
- 深入解析Immutable及 React 中實踐React
- react效能優化React優化
- React 效能優化React優化
- react和immutable偶遇的那些事React
- react/react-native效能優化React優化
- react-效能優化React優化
- React渲染效能優化React優化
- 使用React中後臺效能優化以及移動端優化React優化
- React+Webpack效能優化ReactWeb優化
- React 效能優化總結React優化
- React效能優化總結React優化
- 效能優化-記憶體池的設計和實現優化記憶體
- 這個immutable Data react實踐React
- 「React」如何在React中優雅的實現動畫React動畫
- 通過友盟+U-APM實現人臉識別會議系統效能優化優化
- React Native 效能優化元件-PureComponentReact Native優化元件
- React效能優化方案之PureRenderMixinReact優化
- React效能優化方案之PureComponentReact優化
- 4、React元件之效能優化React元件優化
- React效能優化:PureComponent的使用原則React優化
- React函式式元件的效能優化React函式元件優化
- 如何更好的使用OPcache實現效能優化opcache優化
- 輕鬆實現 Web 效能優化Web優化
- 關於 React 效能最佳化和數棧產品中的實踐React
- 【數字化】如何通過數字化轉型實現生產製造的優化?優化
- 從 React render 談談效能優化React優化
- React 16 載入效能優化指南React優化
- React 效能優化 - 避免重複渲染React優化
- React Native如何做效能優化React Native優化
- 效能優化的過程學習優化
- App監控和效能優化實戰APP優化
- 實時渲染不是夢:通過共享記憶體優化Flutter外接紋理的渲染效能記憶體優化Flutter
- 通過 recompose 實現 react router4 許可權React
- 【譯】21 項優化 React App 效能的技術優化ReactAPP