React vs Angular: медленный рендеринг с React

51

Я делал сравнение Angular и React и решил попробовать тест производительности, чтобы увидеть, как быстро большой (ish) список будет отображаться в обеих фреймах.

Когда я закончил свой прототип 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

Изменить: я открыл проблему с помощью реакции-intl, и мы исследовали и обнаружили, что с помощью https://github.com/yahoo/react-intl/issues/27 не было слишком много накладных расходов - это просто Реагирует на себя что здесь медленнее.

Теги:

8 ответов

42
Лучший ответ

Это определенно интересный тестовый пример.

Если вы посмотрите на временные шкалы, то увидите, что Angular завершил обработку события изменения всего за 20 мс. Оставшаяся часть времени проводится в макете и перекраске.

Изображение 2719

Реакция (с использованием производственной сборки, ваше хранилище по умолчанию использует dev) занимает около 59 мс. Опять же, остальное время тратится на верстку и перекраску.

Изображение 2720

Если вы посмотрите на графики пламени процессора, то увидите, что Angular, похоже, выполняет намного меньше работы.

Угловой:

Изображение 2721

React:

Изображение 2722

React предоставляет довольно хороший хук оптимизации в форме shouldComponentUpdate который особенно полезен, когда один экземпляр компонента из тысяч должен обновиться, а остальные должны остаться прежними; это техника, которую я использую в этой демонстрации (попробуйте в окне инкогнито; я обнаружил, что некоторые расширения Chrome значительно увеличивают время разметки/перерисовки - для меня добавление/удаление отдельных элементов после того, как список длиной 1000 занимает ~ 13 мс, изменение размера/цвета элемента занимает ~ 1 мс). Тем не менее, это не хорошо, когда каждый элемент должен обновляться.

Я предполагаю, что Angular будет быстрее изменять большинство или все элементы в вашей таблице, и React будет достаточно опытным в обновлении записей выбора при использовании shouldComponentUpdate.

  • 1
    Я смотрю на вашу демонстрацию и пытаюсь выяснить, как реагировать на преимущества Virtual DOM / рендеринга. Что я вижу, так это то, что для каждого добавляемого элемента списка макет страницы снова окрашивается (пожалуйста, посмотрите на этот prntscr.com/6qfgqv ). Я в замешательстве - не должен реагировать рендер только то, что изменилось в реальном DOM? Можете ли вы помочь мне понять это?
  • 0
    По поводу моего последнего комментария. После дальнейшего изучения вашей (Awesome !!!) демонстрации (№ 6) я понимаю преимущество реакции, отображающей только новые элементы, а не весь компонент, без необходимости позаботиться об этом. Но, тем не менее, документ будет иметь полный макет / рисование. Разве это не пропускает весь смысл React (опять же, я запутался в этом ..)
Показать ещё 4 комментария
3

Я удивлен, что никто не упомянул PureRenderMixin. Он реализует shouldComponentUpdate, поэтому вам не нужно беспокоиться об этом.

Кроме того, мне интересно, будет ли React Performance Tools что-то полезное?

И я удивлен, услышав, что Angular быстрее, чем React после просмотра этого разговора от Ryan Florence.

2

Мы попытались проанализировать некоторые атрибуты наших фреймворков, конечно, это не весь список. Ниже приведена таблица консолидированного и важного, на наш взгляд, сравнения атрибутов.

Изображение 2723

Позволяет получить более подробную информацию:

Изображение 2724

Изображение 2725

Хотя Angular vs React различий много, они могут делать то же самое, а именно строить клиентский интерфейс. Оба имеют свое место. Для тех народов, которым нравится веб-разработка, прежде всего интересен инновационный подход AngularJS к HTML.

AngularJS действительно представляет собой полную структуру, а не только библиотеку, как ReactJS, но ReactJS имеет лучшую производительность, чем AngularJS, путем внедрения виртуального DOM. По нашему мнению, вы должны использовать AngularJS, если:

  • вы планируете провести много модульных тестов во время разработки,
  • вам нужно комплексное решение для вашего приложения.

Тем не менее, двусторонняя привязка данных часто используется преимуществом использования AngularJS, но поскольку она реализуется посредством серии дайджеста, добавление слишком большой сложности для определенных функций и выражений может привести к ухудшению производительность ваших приложений.

  • 2
    Было бы еще лучше опубликовать таблицы в виде текста для поиска ;)
1

Это пример, когда все, что меняется, - это один вывод данных. Не исключено, что Angular двусторонняя привязка данных просто предлагает более быструю повторную визуализацию, когда все, что меняется, - это отображение связанных данных.

Реакция не обещает, что ее рендеринг быстрее, чем любая другая структура при любых обстоятельствах. То, что он предлагает, - это возможность очень эффективно обрабатывать ~ произвольно сложные DOM-обновления и предлагать различные методы жизненного цикла (например, componentWillReceiveProps, componentDidUpdate, в дополнение к вышеупомянутому shouldComponentUpdate), чтобы вы могли запускать обратные вызовы этих событий и контролировать, как и если они должны произойти. Здесь очень мало оптимизировать, потому что все, что вы делаете, это изменение 2000 текстовых дисплеев.

edit: Чтобы уточнить, React полезен при выполнении более сложных манипуляций DOM, поскольку он виртуальный алгоритм DOM позволяет ему выбирать минимальный набор операций DOM, необходимых для обновления вашей DOM. Это еще много работы, когда все, что должно произойти, - это 2000 экземпляров некоторых изменений текста.

1

В компоненте React, как только вы вызываете setState, он немедленно вызовет функцию рендеринга. React отметит этот компонент как грязный и будет повторно отображать все дочерние элементы внутри этого компонента.

Он не будет отображать все Native-элементы DOM из-за виртуальной DOM, поэтому он все равно будет создавать новые экземпляры своих дочерних ReactElements, что может привести к дополнительной стоимости памяти Javascript.

Чтобы избежать этой проблемы, вам нужна функция mustComponentUpdate, которая реализована в классе компонентов. он будет выполнен до метода Render. Если вы обнаружите, что сейчас ничего не изменилось, например, в вашем примере, вы меняете state.locale. Вы можете определенно подумать, что этот компонент не нуждается в обновлении. поэтому просто верните false, чтобы предотвратить вызов рендеринга.

Это базовое решение для решения проблем производительности React. Попытайтесь добавить "shoudlComponentUpdate" в свой Компонент Numbers, чтобы избежать тонкости повторного рендеринга элементов

1

В этом конкретном случае вам нужно знать, что государство стекает вниз, а также обновляет DOM. То, что вы хотите сделать, это создать компонент Price, который сохраняет локаль в своем собственном состоянии и получает сигнал (т.е. Канал или поток), чтобы изменить локаль, а не посылать языковой опоре полностью вниз. Идея состоит в том, что вам не нужно обновлять весь компонент Numbers, только цены внутри. Компонент может выглядеть так:

var Price = React.createClass({
    mixins: [ReactIntlMixin],
    componentDidMount: function() {
        subscribeToLocal(this.onLocaleChange);
    },
    onLocaleChange: function(newLocales) {
        this.setState({locales: newLocales});
    },
    render: function() {
        return <span>this.formatNumber(this.props.number, this.state.locales, {style: 'currency', currency: 'USD'})</span>
    }
});
  • 1
    Это не будет намного быстрее, и быстрый и грязный тест с EventEmitter показывает, что это так - с 2000 компонентами Price , каналом / хранилищем потоков и т. Д. все равно нужно будет перебрать более 2000 слушателей, и для setState будет вызываться setState .
0

Спасибо всем за участие. React vs Angular - самый актуальный вопрос в настоящее время.

0

Что вы предпочитаете использовать Angular, Vue.js, Node.js или React? Все зависит от характеристик проекта, который вы разрабатываете.

Когда хорошим выбором может быть Angular, а не React или Vue?

В случае, если вы обладаете глубокими знаниями в TypeScript, с прочной основой в объектно-ориентированном программировании (ООП). В разработке надежных и хорошо структурированных приложений.

Когда целесообразно использовать React вместо Angular или Vue?

Рекомендуется, когда у вас есть базовые знания TypeScript. Вы хотите создавать отличные гибкие приложения. React предоставляет большое количество пакетов для разных целей и легко интегрируется с другими библиотеками.

Когда предлагается выбрать Vue по сравнению с Angular или React?

Vue является отличным выбором для проектов или небольших групп программирования. Его кривая обучения намного легче для тех, кто начинает.

Эти две статьи показывают всеобъемлющий сравнительный анализ с точки зрения:

Сравнение между React, Angular и Vue - Часть I

Сравнение между React, Angular и Vue - Часть II

Ещё вопросы

Сообщество Overcoder
Наверх
Меню