6.2.2 性能优化问题
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
6.2.2 性能优化问题
“以函数为子组件”模式可以让代码非常灵活,但是凡事都有优点也有缺点,这种模式也不例外,这种模式的缺点就是难以做性能优化。
每次外层组件的更新过程,都要执行一个函数获得子组件的实际渲染结果,这个函数确实提供了灵活性。但是也因为每次渲染都要调用函数,无法利用shouldComponent-Update来避免渲染浪费,使用高阶组件则可以直接使用shouldComponentUpdate来避免无谓的重新渲染。
可以让外层组件定制自己的shouldComponentUpdate,但是每个组件对这个生命周期函数的定义都不同,无法使用react-redux那种放之四海而皆准的标准。
为了便于理解,我们设想一下如何给CountDown做性能优化。要知道,CountDown也会成为其他组件的子组件,作为子组件,更新过程是可以被父组件触发的,所以我们要预期到CountDown在没有更改props的情况下被要求开始更新过程,为了防止无谓的重新渲染,我们需要借助shouldComponentUpdate函数:
shouldComponentUpdate(nextProps, nextState) {
return nextState.count !== this.state.count;
}
CountDown组件还是比较简单,因为传递给子组件的参数只有this.state.count,所以我们在shouldComponentUpdate中只要看新state上的count值和当前count值是否相同就可以了。
另一个性能问题来自于函数形式的子组件,在上面的例子中,为了代码清晰,我们都使用在JSX直接定义一个箭头函数或者Lambda表达式的方式:
{
(count) => {count}
}
这样用起来当然很方便,但是等于是每次渲染都会重新定义一个新的函数,那么CountDown的shouldComponentUpdate函数应该不应该把this.props.children和nextProps.children比较呢?
严格说是需要的,因为两个函数都不一样了,当然应该重新渲染,但是,如果这么做的话,就要求使用CountDown的地方不能使用匿名函数,比如,在使用CountDown的组件类中定义一个showCount函数,接受一个count参数,代码如下:
showCount(count) {
return {count}
}
然后CountDown就可以把showCount作为子组件使用,代码如下:
{showCount}
这样就失去了代码的灵活性,总之鱼与熊掌不可兼得,开发者要权衡使用。
虽然“以函数为子组件”有这样性能上的潜在问题,但是它依然是一个非常棒的模式,实际上,在react-motion动画库中大量使用这种模式,也没有发现特别大的性能问题。要知道,对于动画功能,性能是最重要的因素,react-motion的用户群没有反映存在性能问题,可见这种模式是性能和灵活性的一个恰当折中。 深入浅出React和Redux