当我完成了我的React原型与一些基本的货币形成,它需要约2秒渲染在我的快速笔记本电脑。有了Angular,它几乎不可察觉 – 只有当我切换到我的手机,它有一个明显的滞后。
这是非常令人惊讶的,因为我被告知,React应该打败Angular的裤子的性能,但在这种情况下,似乎相反的情况是真的。
我把我的原型蒸馏到一个非常简单的应用程序,试图隔离问题:https://github.com/pselden/react-render-test
在这个示例中,改变语言后,花费近200ms来呈现这个简单的列表,我几乎不做任何事情。
我在这里做错了吗?
/** @jsx React.DOM */ 'use strict'; var React = require('react'),Numbers = require('./Numbers'); var numbers = [] for(var i = 0; i < 2000; ++i){ numbers.push(i); } var App = React.createClass({ getInitialState: function() { return { locale: 'en-US' }; },_onChangeLocale: function(event) { this.setState({locale: event.target.value}); },render: function() { var currentLocale = this.state.locale; return ( <div> <select onChange={this._onChangeLocale}> <option value="en-US">English</option> <option value="fr-FR">French</option> </select> <Numbers numbers={numbers} locales={[currentLocale]} /> </div> ); } }); module.exports = App;
/** @jsx React.DOM */ 'use strict'; var React = require('react'),ReactIntlMixin = require('react-intl'); var Numbers = React.createClass({ mixins: [ReactIntlMixin],getInitialState: function() { return { numbers: this.props.numbers }; },render: function() { var self = this; var list = this.state.numbers.map(function(number){ return <li key={number}>{number} - {self.formatNumber(number,{style: 'currency',currency: 'USD'})}</li> }); return <ul>{list}</ul>; } }); module.exports = Numbers;
PS:增加了角度版本:https://github.com/pselden/angular-render-test
编辑:我打开一个问题与反应intl,我们调查,发现没有那么多开销使用https://github.com/yahoo/react-intl/issues/27 – 它只是React本身在这里慢。
如果你看看时间线,你可以看到Angular完成处理改变事件只需20ms。剩余的时间花在布局和重绘。
React(使用生产构建,您的repo默认使用dev)花费大约59ms。再次,剩下的时间花在布局和重绘。
如果你看看cpu火焰图,你可以看到Angular似乎做了很少的工作。
角度:
反应:
。
React以shouldComponentUpdate的形式提供了一个非常好的优化钩子,当一个组件的单个实例应该更新,而其他应该保持不变时,它是特别有用的;它是一个我在this demo使用的技术(试试在一个隐身窗口;我发现一些Chrome扩展使布局/重绘时间更高 – 对我来说,添加/删除单个元素一旦列表是1000长需要〜13ms,元素的大小/颜色需要〜1ms)。然而,当每个元素都需要更新时,它没有好处。
我的猜测是,Angular将更快地更改表中的大多数或所有元素,并且React将非常熟练地使用shouldComponentUpdate更新选择条目。