我对Angular和React进行了比较,并决定进行一次性能测试,看看一个大列表在这两种框架中呈现的速度有多快.

当我用React原型完成一些基本的货币格式化时,在我的快速笔记本电脑上渲染大约需要2秒钟.有了Angular,它几乎不明显——只有当我切换到手机时,它才有明显的滞后.

这是非常令人惊讶的,因为我被告知React应该为了性能而把Angular的裤子脱掉,但在这种情况下,情况似乎正好相反.

我将我的原型提炼为一个非常简单的应用程序,试图找出问题:https://github.com/pselden/react-render-test

在这个示例中,在更改语言后,渲染这个简单的列表几乎需要200毫秒,而我几乎什么都没做.

我做错什么了吗?

/** @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:增加了一个Angular 版本:https://github.com/pselden/angular-render-test

编辑:我打开了react intl的一个问题,我们进行了调查,发现使用https://github.com/yahoo/react-intl/issues/27并没有太多开销——只是react本身的速度较慢.

推荐答案

这绝对是一个有趣的测试用例.

如果你看一下时间线,你会发现Angular在20秒内就完成了对变更事件的处理.剩下的时间用于布局和重新喷漆.

Angular 时间轴

React(使用生产构建,您的repo默认使用dev)大约需要59毫秒.同样,剩下的时间都花在了布局和重新粉刷上.

React Timeline

如果你看一下CPU火焰图表,你会发现Angular做的工作似乎要少得多.

Angular :

Angular CPU图形

react :

react CPU图形

React以shouldComponentUpdate的形式提供了一个非常好的优化钩子,当数千个组件中的一个实例需要更新,而其他实例应该保持不变时,它尤其有用;这是我在this demo中使用的一种技术(在一个不知名的窗口中试用;我发现一些Chrome扩展会使我的布局/重新绘制时间高得多,当列表长度为this demo0时添加/删除单个元素需要约13毫秒,更改元素的大小/ colored颜色 需要约1毫秒).然而,当每个元素都需要更新时,这并没有什么好处.

我猜Angular在更改表中的大部分或所有元素时会更快,而React在使用shouldComponentUpdate时会非常擅长更新 Select 项.

Reactjs相关问答推荐

React onKeyUp不一致地使用快速Shift+键按压

React中的useEffect钩子

可以使用mode.css/mode.scss引用常规的类名吗?

在reactjs中刷新页面时丢失状态值

Chart.js如何go 除边框

在 Next13 中将 props 传递给 onClick 从服务器到客户端组件

如何在 React Hook Form 中使用嵌套对象处理错误验证消息

ReactJS on AWS Amplify与EC2上的Spring boot服务之间的混合内容错误

为什么这个 React 组件会导致无限渲染?

如何在不使用 Axios 的情况下将图像文件从 React.js 发送到 Spring Boot Rest API?

如何使用样式化函数为 TextField 的输入组件设置样式

使用 react pro 侧边栏展开折叠菜单

当我在 useEffect 中使用 useDispatch 时,我的组件继续渲染

将复杂状态和 setState 传递给更简单的 api

React Native - 身份验证 - 触发值以更改 Auth 和 UnAuth 堆栈导航器

如何通过 Material ui select 使下拉菜单下拉

当状态改变时如何执行一些动作,但只针对第一次更新?

React Hooks 表单在日志(log)中显示未定义的用户名

在 Redux 中更新布尔状态时出错

React Router 6,一次处理多个搜索参数