有这样一个场景,有无穷多个dom,可以修改数字,数字对应哪一个dom,则哪一个dom颜色就变红,UI如下
如果不做任何优化,在dom很少的时候,可能感觉不到性能的缺失,但是当dom有100,1000时,就会很明显的感受到dom并不是立即改变的,有一个卡的过程,这主要是由于做了大量的重复渲染造成的,怎么来解决这个问题呢,我做的优化主要是用到了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改变时才会发生,我们可以在shouldComponentUpdate中做判断是否重绘我们的组件,在container组件中,我们已经做处理了,如果selectedIndex不是数字时,是禁止重绘的,我们来看看加不加这一段的区别
我分别输入了0,1,5,从打印的结果来看,多做了两次渲染,这两次渲染是因为每次清除数字时导致的,此时selectedIndex就为NaN了,这造成了浪费,接下来,我们做同样的操作,但是加上shouldComponentUpdate的逻辑
此时就没有浪费了
以上讲的是容器组件,我们还没有对灰色组件做优化,现在我们来看做优化和不做优化的区别
不做优化改一个数字
这很明显,造成了999次重复渲染,当加上这段之后,就没有再重复渲染的情况了
shouldComponentUpdate(nextProps){
return nextProps.render
}
其中的render就是判断selectedIndex和index是否一致,逻辑简单,不展开了