# 一、重新认识render
react的组件渲染分为初始化渲染和更新渲染
- 在初始化渲染的时候会调用根组件下的所有组件的
render方法进行渲染,如下图(绿色表示已渲染,这一层是没有问题的)

但是当我们要更新某个子组件的时候,如下图的绿色组件(从根组件传递下来应用在绿色组件上的数据发生改变)

我们的理想状态是只调用关键路径上组件的render

但是react的默认做法是调用所有组件的render,再对生成的虚拟DOM进行对比,如不变则不进行更新。这样的render和虚拟DOM的 对比 明显是在浪费,如下图(黄色表示浪费的render和虚拟DOM对比)

Tips
- 拆分组件是有利于复用和组件优化的
- 生成虚拟
DOM并进行比对发生在render()后,而不是render()前
# 二、更新阶段的生命周期
componentWillReceiveProps(object nextProps):当挂载的组件接收到新的props时被调用。此方法应该被用于比较this.props和nextProps以用于使用this.setState()执行状态转换。(组件内部数据有变化,使用state,但是在更新阶段又要在props改变的时候改变state,则在这个生命周期里面)shouldComponentUpdate(object nextProps, object nextState): -boolean当组件决定任何改变是否要更新到DOM时被调用。作为一个 优化 实现比较this.props和nextProps、this.state和nextState,如果React应该跳过更新,返回falsecomponentWillUpdate(object nextProps, object nextState) :在更新发生前被立即调用。你不能在此调用this.setState()componentDidUpdate(object prevProps, object prevState) : 在更新发生后被立即调用。(可以在DOM更新完之后,做一些收尾的工作)
Tips
React的优化是基于shouldComponentUpdate的,该生命周期默认返回true,所以一旦prop或state有任何变化,都会引起重新render
# 三、shouldComponentUpdate
react在每个组件生命周期更新的时候都会调用一个shouldComponentUpdate(nextProps, nextState)函数。它的职责就是返回true或false,true表示需要更新,false表示不需要,默认返回为true,即便你没有显示地定义shouldComponentUpdate函数。这就不难解释上面发生的资源浪费了
带坑的写法
{...this.props}(不要滥用,请只传递component需要的props,传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担,因此,也请慎用spread attributes(<Component {...props} />))::this.handleChange()。(请将方法的bind一律置于constructor)- 复杂的页面不要在一个组件里面写完
- 请尽量使用
const element map里面添加key,并且key不要使用index(可变的)- 尽量少用
setTimeOut或不可控的refs、DOM操作 - 数据尽可能简单明了,扁平化
# 四、性能检测工具
React.addons.Perf
react官方提供一个插件React.addons.Perf可以帮助我们分析组件的性能,以确定是否需要优化
react16以前需要在项目中配置,react16以后请看这篇文章,直接打开控制台的perf选项测试 https://reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab
react16之前配置
- 安装
react性能检测工具npm i react-addons-perf --save,然后在./app/index.js中
// 性能测试
import Perf from 'react-addons-perf'
if (__DEV__) {
window.Perf =