React 在不做任何优化的情况下性能也非常好,然而通过一些小小的优化,可以让性能进一步提升,通过以下这6条建议,可以数十倍加快渲染速度
设置 NODE_ENV 为 Production
React 在开发环境下,有完整的警告和错误检查,但它们不是为生产环境准备的,如果你看过 React 的源码,你会看到很多 if (process.env.NODE_ENV != 'production')
,这些代码对于最终用户是不需要的,而且访问 process.env.NODE_ENV
会非常慢,对于生产环境而言,完全可以移除这些代码
如果你使用 Webpack,你可以使用 DefinePlugin 来替换 process.env.NODE_ENV
为 ‘production’,然后使用 UglifyJsPlugin 移除这些不会执行的代码
// webpack.config.js
...
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
...
React 15 的渲染速度比 0.14 快约 25%
在 React 15 的更新中非常重要的一项是,使用在现代化浏览器中性能更好的 document.createElement
替换 innerHTML
,这一改动也意味着 React 将不再支持 IE8
Babel Constant 和 Inline Elements 转换
Babel 为开发者们提供了 React Constant Elements 和 React Inline Elements,这两款插件能够在编译阶段将代码转换成更高效的形式,注意仅将它们用于生产环境
封装集合渲染为独立组件
这一点在循环渲染集合组件时尤其重要,React 在渲染大型集合是性能十分糟糕,原因是 React 会在每次更新中全部重新渲染,因此建议将渲染集合的部分装为独立的组件渲染
// Bad
class MyComponent extends Component {
render() {
const {todos, user} = this.props;
return (<div>
{user.name}
<ul>
{todos.map(todo => <TodoView todo={todo} key={todo.id} />)}
</ul>
</div>)
}
}
// Good
// 当 user.name 更新时,列表不会重新渲染
class MyComponent extends Component {
render() {
const {todos, user} = this.props;
return (<div>
{user.name}
<TodosView todos={todos} />
</div>)
}
}
class TodosView extends Component {
render() {
const {todos} = this.props;
return (<ul>
{todos.map(todo => <TodoView todo={todo} key={todo.id} />)}
</ul>)
}
}
尽早绑定方法
在 render() 中绑定的方法应该尽早声明,而不是在渲染时定义
// Bad
render() {
return <MyWidget onClick={() => { alert(this.state.text) }} />
}
// Good
constructor() {
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.text);
}
render() {
return <MyWidget onClick={this.handleClick} />
}
不变组件禁用更新
对于不需要更新的组件,可以在 shouldComponentUpdate()
中 return false
,或者使用 Stateless Component
// Bad
class Logo extends Component {
render() {
return <div><img src='logo.png' /></div>;
}
}
// Good
class Logo extends Component {
shouldComponentUpdate() {
return false;
}
render() {
return <div><img src='logo.png' /></div>;
}
}
// or Stateless Component
const Logo = () => <div><img src='logo.png' /></div>;
参考文章
原文地址: http://t.cn/RIOBUe4