React 性能优化

如何观察React的性能

可使用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

提取component,使用shouldComponentUpdate

有的时候父组件的一部份内容能够提取一个子组件出来。而后咱们观察这个子组件是否具备独立的更新特征,当子组件的数据没有变化的时候,咱们使用 shouldComponentUpdate 来避免没必要要的从新渲染。
当使用shouldComponentUpdate 方法的时候,咱们能够考虑使用PureComponent。 注意PureComponent使用的是浅比较(===)。api

Recompose

Recompose 是一个React的工具库,提供了大量的函数式组件和高阶组件。帮助你简化定义React 组件,使用相似纯函数组件定义出普通的React组件。具体的api参考官网。数组

Redux

当你使用Redux的时候,connect的Component默认是PureComponent方式,你所要作的是Redux判断组件的props是否相等,用的是===,因此要注意可变对象和不可变对象的合理使用。在reducers里面必定要使用不可变对象定义方式修改全局state,这样才能真正从新选择组件。bash

reselect

为了不Redux在connect的时候没必要要的从新render,要确保mapStateToProps方法在调用的时候不会产生一个新的object。例如不要再用{...object} 或者Object.assign()定义一个新的对象。
进一步可使用reselect库。函数

注意JSX的写法

在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()方法的开销可能比从新渲染还要大,因此不要过分使用。

相关文章
相关标签/搜索