有這樣一個場景,有無窮多個dom,可以修改數(shù)字,數(shù)字對應(yīng)哪一個dom,則哪一個dom顏色就變紅,UI如下

image.png
如果不做任何優(yōu)化,在dom很少的時候,可能感覺不到性能的缺失,但是當(dāng)dom有100,1000時,就會很明顯的感受到dom并不是立即改變的,有一個卡的過程,這主要是由于做了大量的重復(fù)渲染造成的,怎么來解決這個問題呢,我做的優(yōu)化主要是用到了shouldComponentUpdate
看看灰色框組件的代碼
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class Test extends Component {
render() {
const { selectedIndex, index,text } = this.props
return (
<div style={{background: selectedIndex == index ? '#f00' : '#333',width:'100px',height:'100px',margin:'10px'}}>
{text}
</div>
)
}
}
Test.propTypes = {
selectedIndex: PropTypes.number,
index: PropTypes.number
}
Test.defaultProps = {
selectedIndex: -1,
index: 0
}
再看看容器組件的代碼
import React, { Component } from 'react'
import { Link } from 'react-router'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Test from '../../components/Test'
import styles from './main.scss'
// @pureRender
class Perfermance extends Component {
constructor(props) {
super(props)
this.state = {
selectedIndex: -1
}
}
shouldComponentUpdate(nextProps,nextState){
return !Number.isNaN(nextState.selectedIndex)
}
handleInput = (e) => {
this.setState({
selectedIndex: parseInt(e.target.value)
})
}
renderList() {
var lists=[]
for(let i = 0; i <1000; i++){
lists.push(<Test selectedIndex={this.state.selectedIndex} index={i} key={i} text={i} render={this.state.selectedIndex == i} />)
}
return lists
}
render() {
const { colors, texts } = this.state
return (
<div>
<input type="number" onInput={this.handleInput} />
<div className={styles.list}>
{ this.renderList() }
</div>
</div>
)
}
}
const mapStateToProps = state => state
export default connect(mapStateToProps, null)(Perfermance)
先打斷一下,其實react組件重繪,只有在state改變或者props改變時才會發(fā)生,我們可以在shouldComponentUpdate中做判斷是否重繪我們的組件,在container組件中,我們已經(jīng)做處理了,如果selectedIndex不是數(shù)字時,是禁止重繪的,我們來看看加不加這一段的區(qū)別

image.png
我分別輸入了0,1,5,從打印的結(jié)果來看,多做了兩次渲染,這兩次渲染是因為每次清除數(shù)字時導(dǎo)致的,此時selectedIndex就為NaN了,這造成了浪費,接下來,我們做同樣的操作,但是加上shouldComponentUpdate的邏輯

image.png
此時就沒有浪費了
以上講的是容器組件,我們還沒有對灰色組件做優(yōu)化,現(xiàn)在我們來看做優(yōu)化和不做優(yōu)化的區(qū)別
不做優(yōu)化改一個數(shù)字

image.png
這很明顯,造成了999次重復(fù)渲染,當(dāng)加上這段之后,就沒有再重復(fù)渲染的情況了
shouldComponentUpdate(nextProps){
return nextProps.render
}
其中的render就是判斷selectedIndex和index是否一致,邏輯簡單,不展開了