国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

react性能優化達到最大化的方法 immutable.js使用的必要性

2019-11-19 17:13:04
字體:
來源:轉載
供稿:網友

一行代碼勝過千言萬語。這篇文章呢,主要講述我一步一步優化react性能的過程,為什么要用immutable.js呢。毫不夸張的說。有了immutable.js(當然也有其他實現庫)。。才能將react的性能發揮到極致!要是各位看官用過一段時間的react,而沒有用immutable那么本文非常適合你。那么我開始吧!

1、對于react的來說,如果父組件有多個子組件

想象一下這種場景,一個父組件下面一大堆子組件。然后呢,這個父組件re-render。是不是下面的子組件都得跟著re-render。可是很多子組件里面是冤枉的啊!很多子組件的props 和 state 然而并沒有改變啊!!雖然virtual dom 的diff 算法很快,但是性能也不是這么浪費的啊!下面我們上代碼

1).原始代碼如下

以下是父組件代碼。。負責輸入name 和 age 然后循環顯示name 和 age

 export default class extends Component {  constructor(props){  super(props)  this.state={   name:"",   age :"",   persons:[]  }  }  render() {  const {name,age,persons} = this.state  return (   <div>   <span>姓名:</span><input value={name} name="name" onChange={this._handleChange.bind(this)}></input>   <span>年齡:</span><input value={age} name="age" onChange={this._handleChange.bind(this)}></input>   <input type="button" onClick={this._handleClick.bind(this)} value="確認"></input>   {persons.map((person,index)=>(    <Person key={index} name={person.name} age={person.age}></Person>   ))}   </div>  )  }  _handleChange(event){  this.setState({[event.target.name]:event.target.value})  }  _handleClick(){  const {name,age} = this.state  this.setState({   name:"",   age :"",   persons:this.state.persons.concat([{name:name,age:age}])  })   } }

以下是子組件代碼單純的顯示name和age而已

class Person extends Component { componentWillReceiveProps(newProps){ console.log(`我新的props的name是${newProps.name},age是${newProps.age}。我以前的props的name是${this.props.name},age是${this.props.age}是我要re-render了`); } render() { const {name,age} = this.props;  return (  <div>   <span>姓名:</span>   <span>{name}</span>   <span> age:</span>   <span>{age}</span>  </div>  ) }}

運行起來長下圖這個樣


好那么問題來了,我們看一下控制臺:

天哪,這么多次re-reder..細細觀看,不難發現。要re-render這么多次,父組件一re-render,子組件就跟著re-render啊。那么多么浪費性能,好PureRenderMixin出場

2).PureRenderMixin

因為咱用的是es2015的 Component,所以已經不支持mixin了,不過沒關系,可以用HOCs,這個比mixin還更受推崇呢。我有空回用代碼來展示他倆的異同,鑒于不是本文重點,,大家可以看這兩篇文章了解下React Mixin 的前世今生Mixins Are Dead. Long Live Composition

所以在這里我們用Pure render decorator代替PureRenderMixin,那么代碼如下

import pureRender from "pure-render-decorator"...@pureRenderclass Person extends Component { render() { console.log("我re-render了"); const {name,age} = this.props;  return (  <div>   <span>姓名:</span>   <span>{name}</span>   <span> age:</span>   <span>{age}</span>  </div>  ) }}

加個這東西就完事了?看上去咋這么不令人信服啊。不管怎樣,試試吧。


果然可以做到pure render,在必須render 的時候才render。

好我們看看它的神奇之處

@pureRender

是es7的Decorators語法。上面這么寫就和下面這么寫一樣

class PersonOrigin extends Component { render() { console.log("我re-render了"); const {name,age} = this.props;  return (  <div>   <span>姓名:</span>   <span>{name}</span>   <span> age:</span>   <span>{age}</span>  </div>  ) }}const Person = pureRender(PersonOrigin)

pureRender其實就是一個函數,接受一個Component。把這個Component搞一搞,返回一個Component看他pureRender的源代碼就一目了然

function shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState);}function pureRende(component) { component.prototype.shouldComponentUpdate = shouldComponentUpdate;}module.exports = pureRender;

pureRender很簡單,就是把傳進來的component的shouldComponentUpdate給重寫掉了,原來的shouldComponentUpdate,無論怎樣都是return ture,現在不了,我要用shallowCompare比一比,shallowCompare代碼及其簡單,如下

function shallowCompare(instance, nextProps, nextState) { return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);} 

一目了然。分別拿現在props&state和要傳進來的props&state,用shallowEqual比一比,要是props&state都一樣的話,就return false,是不是感覺很完美?不。。這才剛剛開始,問題就出在shallowEqual上了

3).shallowEqual的問題

shallowEqual引起的bug
很多時候,父組件向子組件傳props的時候,可能會傳一個復雜類型,比如我們改下。

 render() { const {name,age,persons} = this.state return (  <div>...省略.....  {persons.map((person,index)=>(   <Person key={index} detail={person}></Person>  ))}  </div> ) }

person是一個復雜類型。這就埋下了隱患,在演示隱患前,我們先說說shallowEqual,是個什么東西,shallowEqual其實只比較props的第一層子屬性是不是相同,就像上述代碼,props 是如下

{ detail:{  name:"123",  age:"123"}}

他只會比較props.detail ===nextProps.detail
那么問題來了,上代碼
如果我想修改detail的時候考慮兩種情況

情況一,我修改detail的內容,而不改detail的引用

這樣就會引起一個bug,比如我修改detail.name,因為detail的引用沒有改,所以props.detail ===nextProps.detail 還是為true。
所以我們為了安全起見必須修改detail的引用,(redux的reducer就是這么做的)

情況二,我修改detail的引用

這種雖然沒有bug,但是容易誤殺,比如如果我新舊兩個detail的內容是一樣的,豈不是還要,render。所以還是不完美,你可能會說用深比較就好了,但是 深比較及其消耗性能,要用遞歸保證每個子元素一樣。

這只是說沒有用immutable引起各種、、、下一篇我講寫,如何用immutable.j。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 秭归县| 卓资县| 南召县| 万盛区| 辰溪县| 和龙市| 罗田县| 德清县| 拉萨市| 广丰县| 灵山县| 麻江县| 金平| 策勒县| 高平市| 乳山市| 广饶县| 固原市| 双流县| 惠安县| 汾阳市| 思茅市| 泉州市| 威信县| 霍州市| 中山市| 仙桃市| 岳阳县| 南充市| 堆龙德庆县| 东乌珠穆沁旗| 健康| 珲春市| 三亚市| 台山市| 沁源县| 偏关县| 公安县| 绵竹市| 上林县| 方城县|