在 url 后加 ?react_pref 可以结合 Chrome 自带的 Performance 做性能测试
单组件优化:
核心: 减少 render 函数执行次数
事件绑定:
在 constructor 中使用 bind 绑定:
- constructor(props) {
- super(props)
- this.eventHandle = this.eventHandle.bind(this)
- }
* 优点: 只需要绑定一次, 并且只会执行一次;
* 缺点: 即使不需要 state 也需要添加 constructor 来绑定, 代码量多一点
在 render 中使用 bind 绑定:
- // ...
- render() {
- return (
- <button onClick={this.clickHandle.bind(this)}></button>
- )
- }
- // ...
* 优点: 写法简单;
* 缺点: 每次执行 render 都会重新执行一次, 多次使用同一个函数需要绑定多次(不推荐使用该方法)
在 render 中使用箭头函数绑定:
- // ...
- render() {
- return ( < button onClick = { () = >this.clickHandle()
- } > </button>
- )
- }
- / / ...
* 优点: 写法简单, 相对于上一种方法性能稍好一点;
* 缺点: 每次执行 render 都要重新生成一个函数
在函数初始化时使用箭头函数绑定(实验性):
- // ...
- clickHandle = () = >{
- // ...
- }
- render() {
- return ( < button onClick = {
- this.clickHandle
- } > </button>
- )
- }
- / / ...
* 优点: 写法简单, 结合了以上三种方法的优点;
* 缺点: 目前是实验性的语法, 需要 babel 转译
总结: 方式一是官方推荐的方式, 也是性能最好的方式; 方法二和方法三有性能问题, 并且当方法作为属性传递给子组件时会触发 re-render, 因为子组件的 props 发生了改变; 方法四是最好的绑定方式, 但是需要结合 babel 转译
属性传递:
由于 js 的特性(对象在内存中的存储), 如果传递的是一个对象, 尽量提前声明一个索引指向该对象, 避免每次 render 都重新在内存中生成一个新的对象
多组件优化:
核心: 减少子组件 render 函数的执行次数(减少子组件的重渲)
定制子组件的 shouldComponentUpdate
当父组件发生了 render, 子组件都会重新渲染很多时候子组件并没有发生任何改变, 它接收到父组件传给它的 props 并没有发生变化, 自身的 state 也没有变化, 这种情况下子组件的无脑重新 render 就可以在其 shouldComponentUpdate()钩子函数里做一些操作这个钩子函数默认返回 true, 即 render 会执行; 我们在里面做些业务上的检测, 再返回 true 或 false 来确定子组件该不该重新渲染
使用 React.PureComponent(React@15.3 新增)
它类似于 React.Component, 区别在于 PurComponent 简单的实现了 shouldComponentUpdate()而 Component 没有实现适用情况: 组件的 render 函数在给定相同的 props 和 state 时渲染相同的结果(纯组件), 可以提升性能
Note(官网上的 Note) React.PureComponents shouldComponentUpdate() only shallowly compares the objects. If these contain complex data structures, it may produce false-negatives for deeper differences. Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data. Furthermore, React.PureComponents shouldComponentUpdate() skips prop updates for the whole component subtree. Make sure all the children components are also pure.
PureComponent 的 shouldComponent()只实现了浅对比, 深对比太消耗性能(对象的深比较需要用到递归, 复杂度太高, 性能消耗太大)
可以使用 immutable 这个库来进行对象的深比较, 复杂度比较低, 但是这个库比较大使用方法参考文档
redux 优化
当我们页面使用的数据需要对获取的 redux 中的数据进行一些处理 (复杂的计算) 才能使用, 并且很多状态是经常切换得时候, 我们可以将那些状态缓存起来, 避免每次切换都重新计算可以使用 react 官方推荐一个库 reselect, 使用方法参考文档
列表类组件优化
当我们渲染一个列表时, 必须给每一项传 key, 否则 react 会报一个警告这个 key 不建议使用数组遍历时的 index, 因为它只能帮助我们消除警告而已, 并没有任何实际意义如果我们在数组前面添加一个元素, 那么 react 会认为所有的元素都发生了改变, 所以全部都重新渲染了, 我们并没有感受到虚拟 DOM 带给我们的优化所以 key 的值必须是唯一的才有意义
来源: https://juejin.im/post/5a7959a96fb9a0635a654686