Конечная битва за производительность между фреймворками JavaScript

Я подумал, что было бы забавно использовать эталонный инструмент Стефана Краузе, чтобы только ради конкуренции провести некоторое сравнение производительности между наиболее известными интерфейсами фреймворки и библиотеки пользовательского интерфейса.

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

Прежде чем читать остальную часть статьи, я хотел бы, чтобы вы кое-что запомнили. Большинство имеющихся UI-библиотек и фреймворков все достаточно быстрые и эффективные. Однако такие проекты, как Svelte, выделяются для меня своим подходом и философией, которым я лично считаю, что они заслуживают большего внимания.

Теперь, когда все это не мешает, возьмите чашку кофе и наслаждайтесь шоу!

Арена

Все тесты были выполнены на моем MacBook Pro со следующими характеристиками:

  • MacBook Pro (Retina, 15 дюймов, середина 2015 г.)
  • Процессор: Intel Core i7 с тактовой частотой 2,2 ГГц
  • Память: 16 ГБ 1600 МГц DDR3
  • Графика: Intel Iris Pro 1536 МБ
  • Браузер: Google Chrome, версия 69.0.3497.100

Команды *

В нашем соревновании по тестированию у нас есть две команды: фреймворки и команда библиотек. В команде фреймворков (Team 1) у нас есть:

В команде UI-библиотек (Team 2) у нас есть:

Битвы

В этом окончательном чемпионате каждая команда изначально будет соревноваться в своих собственных командах. Далее, чтобы было интереснее, победители каждой команды будут соревноваться друг с другом. И, наконец, лучшие исполнители сразятся с бессменным чемпионом PlainJS, также известным как VanillaJS.

Также стоит отметить, что каждая команда будет соревноваться в следующих категориях:

  1. Манипуляции с DOM
  2. Время запуска
  3. Выделение памяти

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

В конце, для удовольствия, я также приведу относительные результаты для самых популярных фреймворков и библиотек: Angular, Inferno, Preact, React и Vue.

Матчи Команды 1

Матчи первого раунда для Команды 1 перечислены ниже:

  • Угловой против Вяза
  • AngularJS против Choo
  • Марионетка против Мифрила
  • Аурелия против Эмбер

Битва 1: Угловой против Вяза

И Angular, и Elm - отличные платформы для создания приложений. Они относительно больше, чем структура, поэтому имело смысл конкурировать друг с другом. Ниже приводится сводка результатов:

Как видно из результатов выше, Angular намного лучше работает в категории манипуляций с DOM. Однако в показателях запуска и в категории памяти Elm в целом работает лучше. Таким образом, Вяз побеждает в этой схватке со счетом 2: 1.

Вяз выигрывает у Angular 6 Optimized

Битва 2: AngularJS против Choo

Переходя к следующему сражению, у нас есть AngularJS против Choo. AngularJS существует некоторое время, и теперь он находится в версии 1.7.1. Более того, с 1 июля 2018 года он вступил в 3-летний период долгосрочной поддержки. Choo - относительно новый фреймворк с меньшими размерами и упором на продуктивность разработчика. Ниже приводится сводка результатов боя:

Как видите, AngularJS в целом лучше работает в категории манипуляций с DOM. Тем не менее, Choo является явным победителем в двух других категориях, что делает Choo победителем со счетом 2: 1.

Choo побеждает AngularJS

Битва 3: Мифрил против Марионетки

И Marionette, и Mithril - очень практичные фреймворки, и я подумал, что было бы интересно сравнить их друг с другом. Ниже приводится сводка результатов:

Как видите, Marionette явно выигрывает в категории манипуляций с DOM. Однако он проигрывает во всех строках категории Startup Metrics. А в категории «Распределение памяти» в целом побеждает Марионетка. И при этом Марионетка выигрывает со счетом 2: 1.

Марионетка выигрывает со счетом 2: 1.

Битва 4: Эмбер против Аурелии

В финальной битве первого раунда мы собираемся сыграть Эмбер с Аурелией. И Ember, и Aurelia - отличные фреймворки с похожей философией, поэтому я подумал, что было бы интересно, если бы они соревновались друг с другом. Ниже приводится сводка результатов:

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

Аурелия побеждает Эмбер со счетом 3: 0

Итак, мы подошли к концу раунда 1. Ниже представлены победители раунда 1:

  • Вяз
  • Чу
  • Марионетка
  • Аурелия

В следующем раунде мы собираемся заставить вышеуказанных участников соревноваться друг с другом, чтобы найти победителя Команды 1.

Команда 1, Раунд 2

В этом раунде нас ждут следующие матчи:

  1. Вяз против Чу
  2. Аурелия против Марионетки

Раунд 2, Битва 1: Вязы против Чу

В следующей таблице приведены результаты:

Глядя на таблицу выше, мы видим, что Choo явно проигрывает Elm в категории DOM. Тем не менее, он выигрывает у Вяза в категории Память. Теперь в категории Startup Elm выигрывает в 3 ряда, что делает его победителем.

Вяз побеждает Чу

Битва 2: Аурелия против Марионетки

В следующей таблице приведены результаты:

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

Марионетка побеждает Аурелию

Команда 1, Финальный раунд

В финальном раунде Марионетка соревнуется с Вязами. Сначала посмотрим на абсолютные значения:

Глядя на абсолютные значения выше, мы видим, что Marionette выигрывает в категории DOM. Но Марионетка проигрывает Вязу в категории «Стартапы». А в категории «Память» побеждает Марионетка с небольшим преимуществом над Вязом.

Теперь посмотрим на сравнительные таблицы:

Глядя на значения выше, мы видим, что Marionette выигрывает в категориях DOM и Memory, но проигрывает в категории Startup. Но в целом Марионетка выигрывает у Вяза.

Марионетка побеждает Вяза

Теперь, когда у нас есть победитель, давайте посмотрим на таблицы сравнения всех конкурентов с победителем, Марионеткой. Давайте начнем с рассмотрения результатов манипуляции с DOM:

Глядя на значения выше, мы ясно видим, что Angular 6 Optimized - единственный конкурент, который явно выигрывает у Marionette. Теперь давайте посмотрим на сравнение времени запуска:

Глядя на таблицу выше, мы видим, что Мифрил и Вяз работают лучше, чем Марионетка. Наконец, давайте посмотрим на сравнение распределения памяти:

Глядя на таблицу выше, мы видим, что Choo - единственный конкурент, который работает лучше, чем Marionette с точки зрения распределения памяти. Теперь, когда Марионетка побеждает в команде 1.

Марионетка побеждает в Команде 1

Матчи Команды 2

Матчи первого раунда для Команды 2 перечислены ниже:

  • React против Vue
  • Preact vs Inferno
  • Svelte vs Redom
  • Бобрил vs Макетт

Битва 1: React vs Vue

И React, и Vue - отличные библиотеки для создания пользовательских интерфейсов на основе компонентов. Вопрос «React vs Vue» задают так много раз, что я решил, что попытаюсь ответить на него, мои могучие таблицы :)

Глядя на значения выше, мы видим, что и React, и Vue очень похожи в категориях «Запуск» и «Память». Но поскольку это соревнование, мы все учтем. Учитывая это, Vue выигрывает в категориях «Запуск» и «Память». Теперь, глядя на категорию DOM, это больше похоже на ничью с небольшим преимуществом перед Vue. И снова, поскольку это соревнование, мне придется выбрать Vue в качестве победителя в этом очень близком матче. Сказав это, глядя на приведенные выше значения, будет справедливо сказать, что вопрос «React vs Vue» не имеет значения с точки зрения производительности, потому что они очень близки друг к другу.

Vue побеждает React, очень близкое совпадение

Битва 2: Preact vs Inferno

И Preact, и Inferno - очень высокопроизводительные и легкие библиотеки пользовательского интерфейса. В связи с этим я подумал, что было бы интересно посоревноваться между ними:

Глядя на таблицу выше, мы можем ясно видеть победы Inferno в категориях DOM и Memory. В категории Startup Preact имеет небольшое преимущество, но в целом Inferno - явный победитель.

Inferno побеждает Preact

Битва 3: Svelte vs Redom

Было непросто решить, с кем будет соревноваться Svelte. Это потому, что Svelte определяет новую категорию библиотек, которые больше похожи на компиляторы, чем на библиотеки. Однако я подумал, что было бы забавно заставить Svelte соревноваться с высокопроизводительной и специализированной библиотекой пользовательского интерфейса, такой как Redom.

Глядя на значения, мы видим, что Redom имеет преимущество в категории DOM. Но Svelte побеждает в категории «Память». Теперь, глядя на категорию Startup, мы видим, что они очень близки. И вообще очень сложно выбрать победителя. Но опять же, поскольку это соревнование, я должен выбрать Redom как победителя, потому что он имеет небольшое преимущество в категории Startup.

Редом побеждает Svelte в очень близком матче

Битва 4: Бобрил против Макетта

Maquette - это реализация виртуальной DOM очень низкого уровня. А Bobril - это компонентная библиотека пользовательского интерфейса, которая использует виртуальную модель DOM и конкурирует с React. Поэтому я подумал, что было бы интересно посмотреть, как Бобрил сыграет против Макетта. Ниже приводится сводка результатов:

Глядя на значения выше, мы видим, что Maquette проигрывает Bobril в категории манипуляций с DOM. Но в категории Startup они очень близки, а у Maquette небольшое преимущество. И, наконец, в категории «Память» можно сказать, что Макетт побеждает Бобрила. В целом можно сделать вывод, что Maquette выигрывает с небольшим преимуществом в категории Startup.

Макетт побеждает Бобрила

Итак, мы подошли к концу раунда 1. Ниже представлены победители раунда 1:

  • Vue
  • Inferno
  • Редом
  • Макет

В следующем раунде мы собираемся заставить вышеуказанных участников соревноваться друг с другом, чтобы найти победителя Команды 2.

Команда 2, Раунд 2

В этом раунде нас ждут следующие матчи:

  1. Vue против Inferno
  2. Редом против Макетта

Раунд 2, Битва 1: Vue vs Inferno

В следующей таблице приведены результаты:

Глядя на приведенные выше значения, становится ясно, что Inferno - победитель во всех трех категориях.

Inferno побеждает Vue

Битва 2: Редом против Макетта

В следующей таблице приведены результаты:

Глядя на таблицы выше, мы видим, что Redom явно выигрывает в категории DOM. В категории Startup они очень близки, Redom имеет небольшое преимущество в размере. И, наконец, в категории «Память» они тоже очень близки друг к другу, но у Redom есть небольшое преимущество. В целом можно сказать, что Redom выигрывает, поскольку он имеет значительно лучшую производительность в категории DOM.

Redom побеждает Maquette

Команда 2, Финальный раунд

В финальном раунде у нас есть Inferno, соревнующийся с Redom. Сначала посмотрим на абсолютные значения:

Глядя на абсолютные значения выше, мы видим, что Inferno - явный победитель в категории DOM. Теперь, глядя на категорию Startup, мы видим, что Redom имеет преимущество. А также в категории памяти Redom в целом имеет преимущество, делая Redom победителем. Теперь давайте посмотрим на сравнительные таблицы и посмотрим, правда ли это:

Мы снова видим, что Inferno - явный победитель в категории DOM, но Redom имеет небольшое преимущество в категориях Startup и Memory. Сейчас действительно сложно выбрать победителя, потому что, если мы увеличим вес категории DOM, Inferno станет явным победителем. В противном случае в целом мы можем сказать, что Redom выигрывает из-за небольшого преимущества в двух других категориях.

Redom побеждает Inferno в целом

Теперь давайте посмотрим на сравнительные таблицы всех конкурентов и победителя, Redom. Давайте начнем с рассмотрения результатов манипуляции с DOM:

Глядя на приведенные выше значения, как и ожидалось, Inferno - явный победитель в категории манипуляций с DOM. Теперь давайте посмотрим на относительные значения в категории Startup:

Глядя на значения выше, мы видим, что все они имеют очень быстрое время загрузки, за исключением Vue и React. В интерактивном ряду Redom побеждает всех остальных участников Команды 2. В основном потоке Maquette имеет преимущество перед Redom. И, наконец, в строке Total Byte Weight Svelte имеет небольшое преимущество перед Redom.

Теперь давайте посмотрим на относительные значения для категории распределения памяти:

Глядя на значения выше, мы видим, что Svelte имеет явное преимущество перед Redom. Но Redom в целом побеждает всех остальных членов команды 2 в категории распределения памяти. Хотя Inferno и Maquette имеют лучшую производительность памяти в двух областях. И с этим Редом становится победителем Команды 2.

Редом побеждает в Команде 2

Битвы победителей

В этом разделе мы рассмотрим результаты битвы между Марионеткой, победителем Команды 1, и Редом, победителем Команды 2. Обратите внимание, что сравнение Редома с Марионеткой похоже на сравнение яблок с апельсинами. Но, в любом случае, давайте сделаем это для развлечения;)

Начнем с абсолютных значений (со стандартным отклонением):

Глядя на приведенные выше значения, мы видим, что и Redom, и Marionette хорошо справляются друг с другом во всех трех категориях. За исключением того, что у Марионетки более медленное время загрузки и она больше по размеру, что и следовало ожидать.

Теперь посмотрим на сравнительные таблицы:

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

Битва с непревзойденным чемпионом

В этом разделе лучшие игроки сразятся с абсолютным чемпионом простым JavaScript. Ниже приведен список:

  • Редом
  • Inferno
  • Svelte
  • Vue
  • Реагировать
  • Preact
  • Марионетка
  • Вяз
  • Чу
  • Угловой 6

Во-первых, давайте посмотрим на абсолютные значения для категории манипуляции с DOM:

Глядя на приведенные выше значения, мы видим, что большинство наших конкурентов находятся в зеленых зонах. Один столбец, который имеет много красных цветов, - это Choo, но в остальном остальные работают довольно хорошо по сравнению с обычным JavaScript. Теперь давайте посмотрим на значения Startup:

Глядя на значения выше, мы видим, что в целом конкуренты находятся в зеленоватой области по сравнению с обычным JavaScript. Однако в строке «Время загрузки скрипта» нужно отметить, что Choo, Vue, Marionette, React и Angular работают медленнее, и этого следовало ожидать, потому что они больше, чем библиотеки пользовательского интерфейса.

Теперь давайте посмотрим на значения в категории «Распределение памяти»:

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

И, наконец, давайте посмотрим на сравнительные таблицы:

Глядя на значения выше, мы видим, что Inferno имеет впечатляющую производительность, за которой следует Angular 6 Optimized. Но Inferno однозначно выигрывает в этой категории. Затем давайте посмотрим на относительные значения Startup:

Глядя на значения выше, мы видим, что Svelte находится на втором месте после Plain JavaScript по общему байтовому весу. А в Bootup Time у нас есть Svelte, Redom, Preact, Elm и Inferno со скоростью 16 мс. В строке «Последовательное интерактивное взаимодействие» у нас есть Redom, очень близкий к обычному JavaScript.

Затем давайте посмотрим на относительные значения в категории «Память»:

Глядя на приведенные выше значения, мы ясно видим, что Plain JavaScript выигрывает у всех лучших исполнителей в категории «Память».

Рассматривая все приведенные выше результаты для простого JavaScript, мы можем сделать следующие выводы:

  • Обычный JavaScript работает лучше с точки зрения использования памяти по сравнению со всеми лучшими исполнителями.
  • Что касается производительности DOM-манипуляций, Inferno и Angular 6 Optimzed в целом работают лучше, чем Plain JavaScript.
  • В категории Startup Svelte, Redom, Preact, Elm и Inferno имеют очень быстрое время загрузки, подобное обычному JavaScript.
  • По общему байтовому весу Svelte, Redom, Preact очень похожи на Plain JavaScript в категории UI-библиотек. В категории фреймворков у нас есть Elm и Choo в зеленоватой области относительно обычного JavaScript.
  • С точки зрения постоянной интерактивности и затрат на работу с основным потоком, не очень легко делать выводы, глядя на таблицы. Но можно сказать, что Redom ближе всего по производительности к Plain JavaScript.

Angular vs Vue vs React vs Preact vs Inferno

Как и обещал, я собираюсь включить сравнительные таблицы по известному вопросу:

Angular vs Vue vs React vs Preact vs Inferno

Я собираюсь представить таблицы, но предоставлю читателям возможность сделать свои собственные выводы. Начиная с исходных значений, мы имеем:

Теперь давайте посмотрим на относительные таблицы. Сначала у нас есть значения, относящиеся к React:

Далее у нас есть значения относительно Vue:

Далее у нас есть значения по сравнению с Preact:

Далее у нас есть значения по сравнению с Angular 6 (оптимизировано):

И наконец, у нас есть значения относительно Inferno:

Заключение

Тестирование производительности - горячая тема, и говорить о ней сложно. Однако в этой статье я попытался дать отправную точку тем, кто интересуется этой темой. Как упоминалось ранее, вы всегда должны запускать свои собственные тесты, создавать прототипы и оценивать варианты на основе требований вашего проекта. Дайте мне знать, что вы думаете, я хотел бы услышать ваши мысли.

Приложение 1

Для справки ниже приведен список всех фреймворков и библиотек, упомянутых в статье, отсортированных по звездочкам на Github от самого высокого до самого низкого:

  1. Vue: 115,033
  2. Реакция: 112 075
  3. AngularJS: 59 139
  4. Угловой: 41049
  5. Preact: 20192
  6. Эмбер: 20 043
  7. Инферно: 12 939
  8. Аурелия: 10 641
  9. Мифрил: 9 543
  10. Нокаут: 9 146
  11. Стройный: 8 069
  12. Марионетка: 7 171
  13. Выбор: 5676
  14. Редом: 1,464
  15. Макет: 657
  16. Apprun: 439
  17. Бобрил: 300
  18. Излишек: 299
  19. ivi: 181 (TypeScript)

Приложение 2

Вот еще несколько скриншотов, сделанных непосредственно из интерактивного инструмента Стефана, которые включают больше результатов. Все значения отсортированы по общему размеру байта:

Сноски:

  1. Было довольно сложно разделить фреймворки и библиотеки на отдельные команды. Простейшим решением было просто сказать «фреймворки», а не «библиотеки». Например, я действительно не мог решить включить Vue в Команду 1 или Команду 2. Я наконец решил включить его в Команду 2.
  2. Я использовал Angular v6.1.0 Optimized для всех тестов.
  3. Svelte - это не библиотека пользовательского интерфейса, а компилятор. Для простоты я сгруппировал Svelte по UI-библиотекам.