改善対象
配列を繰り返し処理によって表示しており、ソートや絞り込み等が行われる場合、レンダリングコストや繰り返し表示する数によっては、何も意識せずに実装した時に著しくパフォーマンスが悪くなることがあります。
そういった時に、パフォーマンス低下を防ぐ簡単な方法をひとつご紹介します。
Step1: Componentを改善する
React.PureComponent
や shouldComponentUpdate
などを用いて再レンダリングを制御する。
shallowEqualの判定を考慮して使い分けが必要です。
例
items = [{value: 1}, {value: 2}, {value: 3}]
{items.map(item => (
<Item obj={item} />
))}
React.PureComponent
Class Item extends React.PureComponent {
render() {
return <div>{this.props.obj.value}</div>
}
}
shouldComponentUpdate
Class Item extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.obj.value !== nextProps.obj.value
}
render() {
return <div>{this.props.obj.value}</div>
}
}
改善例
表示していたListが下記のように並び順が変わった場合
items = [
{value: 1}, // key: 1
{value: 2}, // key: 2
{value: 3} // key: 3
]
items = [
{value: 3}, // key: 1
{value: 2}, // key: 2
{value: 1} // key: 3
]
{value: 2}
はkeyが変わらずかつ shouldComponentUpdate
で比較されているobj.value
の値も同じため、
{value: 2}
のComponent(<Item />
)は再レンダリングされなくなります。
※ この例では、keyを指定していないためデファルトでindexが使われています。
Step2: ユニークかつ適切なkeyを指定する
shouldComponentUpdate と key を 利用
※ PureComponentの例は省略します。
Class Item extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.obj.value !== nextProps.obj.value
}
render() {
return <div>{this.props.obj.value}</div>
}
}
{items.map(item => (
<Item key={item.obj.value} obj={item.obj} />
))}
改善例
表示していたListが下記のように並び順が変わった場合
items = [
{value: 1}, // key: 1
{value: 2}, // key: 2
{value: 3} // key: 3
]
items = [
{value: 3}, // key: 3
{value: 2}, // key: 2
{value: 1} // key: 1
]
この例では、keyが変わらずかつobj.value
の値も同じため、
すべてのComponent(<Item />
)が再レンダリングされなくなります。
DEMOページ