可使用react自带的Component Profiling工具,在页面的url后面添加"?react_perf",就能够在chrome的调试器里面使用Performance tab页记录性能。react
经过观察性能的瓶颈,咱们找出能够优化的地方。仔细分析瓶颈产生的缘由,咱们而已借助高阶函数HOC 给想要优化的组件添加console.log().git
咱们知道,组件从新渲染的代价比较高。尤为是包含不少子组件的外层组件,那么咱们能够在外层组件渲染的时候打印出来。实现方法:github
// in src/log.js
const log = BaseComponent => props => {
console.log(`Rendering ${BaseComponent.name}`);
return <BaseComponent {...props} />;
}
export default log;
// in src/MyComponent.js
import log from './log';
export default log(MyComponent);复制代码
这样咱们能够观察组件是否频繁被从新渲染。chrome
有的时候父组件的一部份内容能够提取一个子组件出来。而后咱们观察这个子组件是否具备独立的更新特征,当子组件的数据没有变化的时候,咱们使用 shouldComponentUpdate 来避免没必要要的从新渲染。
当使用shouldComponentUpdate 方法的时候,咱们能够考虑使用PureComponent。 注意PureComponent使用的是浅比较(===)。api
Recompose 是一个React的工具库,提供了大量的函数式组件和高阶组件。帮助你简化定义React 组件,使用相似纯函数组件定义出普通的React组件。具体的api参考官网。数组
当你使用Redux的时候,connect的Component默认是PureComponent方式,你所要作的是Redux判断组件的props是否相等,用的是===,因此要注意可变对象和不可变对象的合理使用。在reducers里面必定要使用不可变对象定义方式修改全局state,这样才能真正从新选择组件。bash
为了不Redux在connect的时候没必要要的从新render,要确保mapStateToProps方法在调用的时候不会产生一个新的object。例如不要再用{...object} 或者Object.assign()定义一个新的对象。
进一步可使用reselect库。函数
在JSX中避免使用{{}}方式直接定义object。由于这种方式每次都会产生一个新数据。工具
//bad
import React from 'react';
import MyTableComponent from './MyTableComponent';
const Datagrid = (props) => (
<MyTableComponent style={{ marginTop: 10 }}>
...
</MyTableComponent>
)
//good
import React from 'react';
import MyTableComponent from './MyTableComponent';
const tableStyle = { marginTop: 10 };
const Datagrid = (props) => (
<MyTableComponent style={tableStyle}>
...
</MyTableComponent>
)复制代码
// bad
const MyComponent = (props) => <div>{React.cloneElement(Foo, { bar: 1 })}</div>;
// good
const additionalProps = { bar: 1 };
const MyComponent = (props) => <div>{React.cloneElement(Foo, additionalProps)}</div>;复制代码
当一个父组件中有纯函数定义的组件时,合理使用compose的onlyUpdateForKeys。避免子组件没必要要的从新render。性能
import { CardActions } from 'material-ui/Card';
import { CreateButton, RefreshButton } from 'admin-on-rest';
import onlyUpdateForKeys from 'recompose/onlyUpdateForKeys';
const Toolbar = ({ basePath, refresh }) => (
<CardActions>
<CreateButton basePath={basePath} />
<RefreshButton refresh={refresh} />
</CardActions>
);
export default onlyUpdateForKeys(['basePath', 'refresh'])(Toolbar);复制代码
使用React开发项目,每当遇到性能瓶颈的时候,首先使用react-addons-perf来观察瓶颈出现的地方,而后借助辅助工具抽丝剥茧找出问题根源。最后使用shouldComponentUpdate等方式避免没必要要的组件render,这种方式是最有效的。可是也要注意很小的组件调用pure()方法的开销可能比从新渲染还要大,因此不要过分使用。