Как оказалось, выбор версии ES для сборки веб-приложения, а также организация самой этой сборки, может оказаться весьма сложной задачей. Особенно, если вы собираетесь делать этот выбор, основываясь исключительно на доказательной базе. В этой статье я постараюсь ответить на следующие вопросы, возникшие в ходе моего расследования на эту тему:
Как влияет компиляция кода под ES5 на производительность сайта?
Какой инструмент генерирует самый производительный код - TypeScript Compiler, Babel или SWC?
Влияет ли современный синтаксис на скорость чтения браузером JavaScript кода?
Можно ли добиться реального уменьшения объёма бандла с учетом использования Brotli или GZIP, если компилировать код в более высокой версии ES?
Действительно ли нужно собирать сайты под ES5 в 2023 году?
А также как мы реализовали переход на более высокую версию ES, и как изменились наши метрики.
Для ответа на вопросы 1-3 я даже создал полноценный бенчмарк, а четвертый вопрос я решил проверить на нашем реальном проекте с большой кодовой базой.
Компилировать под ES5 плохо?
Итак, начнём. Ежегодно добавляемые в EcmaScript фичи помогают разработчикам все больше сокращать кодовую базу проектов и все сильнее повышать читаемость кода. Настроив процесс сборки своего продукта, настроив компиляцию, а также добавив полифилы, разработчики получают возможность использовать самую свежую версию ES в исходном коде.
А для тех, кто позабыл, почему необходимо настраивать сборку, я кратко напомню. Условная функция Array.prototype.at
появилась только в ES2022, и какой-нибудь Chrome версии ниже 92 о существовании такой функции не знает. Следовательно, если вы будете её использовать и об обеспечении обратной совместимости не подумаете, все пользователи старых версий Chrome не смогут в полной мере пользоваться вашим сайтом.
Пример организации обратной совместимости
Обеспечение обратной совместимости может достигаться двумя способами. Во-первых, вы можете добавить полифилы.
// После добавления этих импортов
import "core-js/modules/es.array.at.js";
import "core-js/modules/es.array.find.js";
// Вы можете без страха использовать эти функции
[1, 2, 3].at(-1);
[1, 2, 3].find(it => it > 2);
А во-вторых, вы можете использовать компилятор, который превратит код современного синтаксиса, в код, поддерживаемый старыми браузерами.
// Например, такой код
const sum = (a, b) => a + b;
// При помощи Babel или другого компилятора можно превратить в такой
var sum = function sum(a, b) {
return a + b;
};
Что ж, необходимость той самой организации обратной совместимости мне никогда особо не нравилась. Ведь она подразумевает обязательную генерацию дополнительного кода, что в свою очередь означает увеличение размера бандла, засорение оперативной памяти, а также, возможно, снижение производительности приложения. И все это при условии того, что большинство (по крайней мере в нашем случае) клиентов имеют относительно свежую версию браузера, а значит для них процесс организации обратной совместимости может быть потенциально деструктивным.
Потому мне и стало интересно ответить на вопросы, которые я указал еще в начале статьи. Свое исследование я решил начать с создания бенчмарка. Цель: изолированная оценка производительности фич в сборках, скомпилированных под ES5 разными инструментами (TypeScript, Babel, SWC), а также в сборке без компиляции.
Эксперимент ставился только над фичами, требующих компиляции, такие как классы или асинхронные функции. Фичи, завязанные на использовании полифилов я решил не тестировать, т.к. если в браузере уже есть реализация всё того же Array.prototype.at
, полифилы стараются не вставлять вместо нее собственную реализацию.
Описание бенчмарка: тест скорости парсинга и производительности
Как я и написал выше, я собираюсь оценить каждый возможный сборщик в отдельности, т.к. результаты генерации кода одного сборщика могут отличаться от результатов другого. Поэтому в бенчмарке для проверки каждой фичи я создал сборки, собранные при помощи TypeScript, SWC и Babel. Вы можете возразить, что неплохо было бы проверить ещё ESBuild, но на момент написания статьи он генерировать код стандарта ES5 был не способен, поэтому его я не рассматривал.
Пример разницы генерируемого кода
// Этот код
const sum = (a = 0, b = 0) => a + b;
// Babel скомпилирует в такой код
var sum = function sum() {
var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return a + b;
};
// А TypeScript в такой
var sum = function (a, b) {
if (a === void 0) { a = 0; }
if (b === void 0) { b = 0; }
return a + b;
};
Помимо трех указанных сборок, я создал еще одну, в которой код тестируемой фичи оставался нетронутым. Её я далее по тексту буду называть современной.
Мне так же было интересно проверить, как работают разные фичи в разных браузерах. Ведь браузеры могут иметь разные движки или хотя бы разный набор оптимизаций. А значит и результаты бенчмарка потенциально могут отличаться от одного браузера к другому. И как раз для автоматизации сбора метрик в разных браузерах я создал небольшой HTTP сервер на NodeJS.
Каждый тест подразумевает запуск сгенерированного HTML файла N раз с задержкой между запусками. Каждый запуск производился в новой вкладке браузера в приватном режиме. По открытию HTML файла браузер запускает JavaScript код, а после его выполнения отправляет в HTTP сервер запрос с результатом прогона итерации теста. Таким образом я пытался получить метрики, которые бы были максимально коррелированы с метриками First Paint, Last Visual Change и другими схожими.
![Визуализация работы бенчмарка Визуализация работы бенчмарка](https://habrastorage.org/getpro/habr/upload_files/105/f83/183/105f83183f8aab7ac63c97b7955773d4.png)
По большей части бенчмарк я создавал для определения производительности фич, но посмотреть на влияние фич на скорость парсинга мне тоже было интересно. Поэтому для оценки скорости парсинга я создал 4 дополнительные сборки, в которых по большей части просто размножил код из сборок для измерения производительности. А далее я просто замерял, сколько нужно времени браузеру, чтобы прочитать содержимое элемента script
.
Результаты бенчмарка: не все так однозначно
Мы постепенно подошли к секции с результатами. В ней я для каждой версии стандарта ES а также для каждой синтаксической фичи составил график. В каждом графике показывается скорость выполнения кода для каждой из сборок в каждом из браузеров. Самая длинная линия на графике означает, что сборка отработала быстрее всего.
Будьте осторожны - теста и графиков в этом блоке получилось много!
Оценка производительности ES фич
ES2015 (ES6)
![](https://habrastorage.org/getpro/habr/upload_files/5e6/b05/13f/5e6b0513fa99e3790ed2270b138caed2.png)
Стрелочные функции. Как оказалось, разница в скорости вызова обычной и стрелочной функций действительно есть. Правда, наблюдается она только в Chrome, Opera и других V8 браузерах. В них стрелочные функции работают на 15% медленнее. По всей видимости в этих браузерах контролировать контекст, в котором функция была создана, сложнее, чем использовать собственный контекст для каждой функции.
![](https://habrastorage.org/getpro/habr/upload_files/497/e71/3c5/497e713c5b4fc36aa4d4bc313e7bf335.png)
Классы. В этом тесте видна огромная пропасть в результатах у разных компиляторов. Использование современной и TypeScript конфигураций показали более быстрые результаты. В основном, современная конфигурация показывает себя производительнее всех, однако Safari лучше отработал с TypeScript. Babel и SWC же сгенерировали код в 2-3 раза медленнее.
![](https://habrastorage.org/getpro/habr/upload_files/834/a8d/c70/834a8dc709452f9526eedf5bab7fcae7.png)
В тесте использования параметров по умолчанию итоги абсолютно противоположные. SWC и Babel показывают схожие результаты и отрабатывают быстрее всего. Самой медленной оказалась сборка от TypeScript. Современная же недалеко ушла от TypeScript, но все же показывает себя немножко эффективнее.
![](https://habrastorage.org/getpro/habr/upload_files/20f/7fa/25c/20f7fa25c7fada150b73511f1b18b8ff.png)
Итерирование при помощи конструкции for .. of. Снова все рекорды бьёт TypeScript. Далее идут современная сборка, SWC и в конце находится Babel.
![](https://habrastorage.org/getpro/habr/upload_files/799/2f0/8c9/7992f08c95156feee3254d57effd4c46.png)
Генераторы. Среди сборщиков Babel показал самый быстрый результат. С современной сборкой не все так однозначно. В Safari она показала себя эффективнее, чем Babel. Но при этом в Firefox она же является самой медленной. По всей видимости, разработчики Firefox не особо думали об оптимизации работы генераторов. Но если не брать в расчет этот браузер, то я бы сказал, что современная сборка делит первое место с Babel, а SWC и TypeScript вместе стоят на втором.
![](https://habrastorage.org/getpro/habr/upload_files/61d/7c2/d09/61d7c2d099bed668fceb6f74dc561ac9.png)
В тесте использования вычисляемых свойств объектов ситуация тоже неоднозначная. В целом, TypeScript и современная сборки являются самыми производительными, в Firefox и Safari первенство у TS, в V8 браузерах у современной. Судя по графику Babel оказался самым медленным, но, думаю, это произошло вследствие некоторого сайд эффекта, и в реальном проекте результаты SWC и Babel были бы одинаковы.
![](https://habrastorage.org/getpro/habr/upload_files/937/bf7/863/937bf7863396a32def12bd8a765cfdc2.png)
Крайне однозначные итоги вышли в тесте использования rest параметра. Самая производительная конфигурация - современная, самая медленная - TypeScript.
![](https://habrastorage.org/getpro/habr/upload_files/65a/957/e61/65a957e61d8245abc3de6f083842d3d1.png)
Spread оператор. Однозначно быстрее себя показала современная сборка. В Chrome и Opera разница составила аж 4 раза. Остальные же конфигурации показали себя примерно на одном уровне, однако в Firefox TypeScript отработал слегка медленнее.
![](https://habrastorage.org/getpro/habr/upload_files/601/6a8/837/6016a88374b9b638883dc1769e675581.png)
Шаблонные строки - опять же, однозначно производительнее себя показала современная сборка. Какой-либо разницы в сборках разными инструментами нет.
ES2016
![](https://habrastorage.org/getpro/habr/upload_files/d26/109/65e/d2610965e7c59d81fb21d8d43945e35d.png)
Оператор возведения в степень. Разница настолько невелика, что заметить её сложно. Все в пределах погрешности.
ES2017
![](https://habrastorage.org/getpro/habr/upload_files/4f4/e6e/bc7/4f4e6ebc74a83d027e0a79f1beb61030.png)
Асинхронные функции. Современная сборка снова на первом месте. Наибольший отрыв в Safari - до 20%. Небольшая разница между другими конфигурациями наблюдается, но однозначных выводов сделать не получится - в Chrome и Opera Babel является самой медленной сборкой, а в Firefox самой быстрой.
ES2018
Формально говоря, в этом году появилось всего 2 синтаксических фичи - rest и spread операторы в объектах. Однако, я подумал, что 2х тестов может быть недостаточно. А все потому, что в зависимости, от того, как были использованы эти операторы, разные инструменты генерируют код по разному.
Вот ссылка на песочницы выбранных сборщиков, если вы желаете посмотреть на разнообразие генерируемого кода:
Начнем с простого. Для оценки rest оператора я создал два теста - в одном я просто копирую объект, а в другом я беру из объекта несколько пропертей.
![](https://habrastorage.org/getpro/habr/upload_files/365/ed6/de2/365ed6de2830db0a53d24d5c34b3178a.png)
В первом случае rest оператор показал довольно интересные итоги. Браузеры будто разделились на два лагеря: Chrome и Opera оптимизированы для работы с кодом от TypeScript, затем по скорости себя лучше всего показывает современная сборка, а Babel и SWC плетутся в конце; но в Firefox и Safari ситуация абсолютно обратная - TypeScript работает медленнее всего, а результаты по остальным сборкам почти не отличаются.
![](https://habrastorage.org/getpro/habr/upload_files/fed/f9d/d4b/fedf9dd4be0de25f14d6d22e0cfc96fc.png)
Во втором случае во все тех же Safari и Firefox современная конфигурация всех разрывает. А вот в Opera и Chrome она является самой медленной. Из сборщиков TypeScript снова оказался немного медленнее остальных сборок.
Теперь по spread оператору. Я написал 4 теста, используя spread оператор в разных конфигурациях. Но независимо от того, как я применял оператор, результаты бенчмарка оказались схожи с итогами по rest оператору - современная и TS сборки шустро работают в Safari и Firefox, но настолько же медлительно в Chrome и Opera.
![](https://habrastorage.org/getpro/habr/upload_files/f8f/c92/bba/f8fc92bbaac2c9ee83687da5fb0cdae1.png)
Во всех тестах наблюдается примерно такая картина. Но если вам интересно посмотреть на все результаты, можете их изучить в репозитории.
ES2018 Bonus
![](https://habrastorage.org/getpro/habr/upload_files/b46/0e1/8b0/b460e18b09e6025466ff5155fa269f1f.png)
Забавный факт, который я обнаружил, пока писал бенчмарк. Если уже посмотрели на исходный код тестов, то заметили, как я в качестве ключей использовал значения 'a' + i
. И делал я это не случайно! Ведь если в качестве ключа в объекте использовать число, то по неведомой мне причине в Chrome и Opera современная сборка начинает отрабатывать невероятно быстро. Причем не просто быстрее других сборок в этих же браузерах, но даже быстрее, чем Firefox или Safari, хотя в тестах выше они показывали свое превосходство.
ES2019
![](https://habrastorage.org/getpro/habr/upload_files/53f/29a/02a/53f29a02ab1f31b573f92efb778adebe.png)
Приватные поля в классах. Снова безоговорочная победа за современной сборкой. А TypeScript показывает неплохие результаты, не считая тестов в Safari, однако полагаться на них не стоит. TypeScript в отличии от остальных сборщиков не способен компилировать приватные переменные в ES5.
ES2020
![](https://habrastorage.org/getpro/habr/upload_files/a05/f15/48c/a05f1548cd84bc2673db104b9dc67d4d.png)
Оператор нулевого слияния. Снова безоговорочная победа за современной конфигурацией. А Babel показал себя хуже всего.
![](https://habrastorage.org/getpro/habr/upload_files/770/859/a98/770859a98b183f665fbd8e1cec1d54ad.png)
Оператор опциональной последовательности. TypeScript себя показал хуже остальных сборок, а в остальном разницы нет.
ES2021
Логические операторы. Мне было интересно проверить по отдельности как они работают, когда присваивание выполняется и когда нет.
![](https://habrastorage.org/getpro/habr/upload_files/0d8/22e/34c/0d822e34ce1aa741abf1824dd91e1b97.png)
В первом случае современная сборка показывает себя чуть хуже других сборок, а разницы между сборщиками не наблюдается.
![](https://habrastorage.org/getpro/habr/upload_files/38d/888/893/38d888893c406770bded39ff2517edbc.png)
А во втором случае современная сборка на пару с TypeScript показывают свое превосходство над другими сборками.
ES2022
![](https://habrastorage.org/getpro/habr/upload_files/01e/732/a44/01e732a447f61ef048abb56d18ddaf36.png)
Приватные методы в классах. Результаты такие же, как и в тесте использования классов. А ещё TypeScript все так же не способен использовать приватные модификаторы в ES5. Но в ES6 соотношение результатов остается таким же.
Оценки скорости парсинга
Вообще тренд на повышение скорости парсинга был популярен ещё в эпоху OptimizeJS. С тех пор прошло немало времени, сам разработчик той библиотеки пометил её устаревшей, а разработчики V8 описали практики, применяемые в ней, деструктивными. Потому, сейчас фронтэнд разработчики как-то и не гоняются особо за парой выигранных миллисекунд. И я не собирался, конечно. Но все же мне было интересно, может ли использование современного синтаксиса повлиять на скорость чтения браузером JavaScript кода.
Я запустил тест и получил таки парочку интересных результатов. Например, оказалось, что Safari считывает стрелочные функции медленнее, чем обычные, несмотря на то, что файл со стрелочными функциями имеет наименьший размер.
![](https://habrastorage.org/getpro/habr/upload_files/382/022/c5a/382022c5a9c791b01c1eb38036bff195.png)
А Firefox довольно долго обрабатывает код с приватными полями в классе. Причем забавно, что приватные методы он считывает без особых сложностей.
![](https://habrastorage.org/getpro/habr/upload_files/95f/103/ddb/95f103ddbe0d60e87448a0559f985418.png)
На этом интересные факты заканчиваются. В остальных случаях в результатах бенчмарка прослеживается четкая зависимость времени от количества символов в сгенерированном коде, что означает, что в остальных случаях парсинг современной сборки показал себя эффективнее всего. Если желаете подробно ознакомиться с результатами, вот ссылка.
Краткое резюме по бенчмарку
Весь описанный выше текст можно резюмировать тремя основными идеями.
Во-первых, современная сборка абсолютного превосходства над ES5 не имеет и нередко даже отрабатывает медленнее. Однако, она является самой быстрой в большинстве случаев.
Во-вторых, идеального инструмента для сборки самого производительного кода в ES5 нет. Как минимум из-за того, что разные браузеры имеют разные оптимизации. Но вы можете подобрать для себя наилучшее соотношение плюсов и минусов. Например, если вдруг в вашем приложении генератор генератором погоняется, Babel будет весьма очевидным выбором, а если в нем очень много классов, стоит посмотреть в сторону TypeScript.
Я бы сказал, что TypeScript часто показывает себя лучше других инструментов. Однако, меня расстраивает, что в некоторых тестах, где он хорошо себя чувствует в Safari, в Chrome он способен показать наихудший результат. Особенно учитывая тот факт, что пользователей на Chrome большинство.
И в-третьих, мы можем сделать вывод о том, что не все браузеры уделили внимание оптимизации работы с современным синтаксисом. Firefox ужасно работает с генераторами, Chrome несовершенно организовал spread в объектах, и т.п. Однако, думается мне, что если браузеры и будут заниматься подкапотными оптимизациями, с большей вероятностью они будут внимание уделять современному синтаксису. Так что кто знает, может через пару лет современная сборка станет однозначно самой быстрой.
А что по объёму файлов?
Любимая фраза разработчиков, до сих пор компилирующих под ES5 звучит так:
"Ну так а смысл гоняться за уменьшением размера бандла? Средства сжатия всю эту разницу все равно нивелируют."
А правы ли они в своих рассуждениях, мы с вами сейчас и узнаем.
Этот пункт я решил проверить на своем рабочем проекте, т.к. сжатие является довольно комплексным процессом, а потому проводить оценку по отдельности для каждой фичи было бы не совсем честно.
На время тестов я убрал подключение полифилов из сборки. Затем я собрал наш проект каждым из указанных инструментов, сжал их при помощи GZip и Brotli, и посчитал суммарный объём созданных чанков приложения. И вот такие результаты у меня получились:
Raw |
GZip |
Brotli |
|
Modern |
6.58 Мб |
1.79 Мб |
1.74 Мб |
TypeScript |
7.07 Мб |
1.82 Мб |
1.86 Мб |
Babel |
7.71 Мб |
1.92 Мб |
1.86 Мб |
SWC |
7.60 Мб |
1.94 Мб |
1.86 Мб |
Вы можете удивиться тому, что на TypeScript Brotli показал результат хуже, чем у GZip. Это произошло из-за того, что я запускал Brotli с уровнем сжатия 2 (максимальный - 11). Этот уровень сжатия я решил выбрать, т.к. он максимально близок к настройкам, применяемых в Cloudflare по умолчанию, и этот CDN мы используем в нашем продукте.
И что же мы видим? Размер проекта действительно уменьшился на 7-15%, что в сыром, что в сжатом состоянии. И тут уж как посмотреть - для кого-то такая разница будет незначительной, а кому-то, наоборот, покажется существенной. Для себя в компании мы решили, что это разница достаточно велика, чтобы попытаться прикрутить более современную сборку на прод.
Выходит, современная сборка получает ещё одну победу.
Ну и ещё вместе с этим, в таблице видно, как TypeScript показывает свое превосходство в плане объема генерируемого кода над другими библиотеками.
Так ли важны 4%?
Из всего описанного выше можно сделать простой вывод. Пользователи получат более приятный UX, если ваш продукт будет скомпилирован в более высокой версии ES. Ваше веб-приложение станет более производительным, а также станет меньше весить.
Однако, вместе с этим нужно понимать, что по данным Browserslist поддержка ES2015 на данный момент есть только у 96% пользователей по всему миру, ES2017 у 95%, а у более высоких версий поддержка ещё ниже.
Поэтому вывод можно сделать такой:
Всякие ситуации бывают, и если вам не так уж важны эти 4% пользователей с устаревшими браузерами, то логичнее будет собирать сайт в свежей версии ES. Например, в ES2018.
Если все же они важны, но у вас не очень большой проект, или вам не сильно важен прирост в качественных метриках, можете собираться под ES5. Производительность от этого не пострадает критическим образом.
Но если для вас важны и пользователи с устаревшими браузерами, и даже легкий прирост в производительности, вам стоит задуматься над созданием двух сборок - современной и ES5 - и продумать то, как доставлять пользователю нужную сборку. Именно так мы и поступили в нашей компании.
Наш опыт использования современной сборки
Вообще идея о разделении сбороĸ в нашем продуĸте появилась задолго до моего появлении в ĸомпании Mayflower, я просто немного её развил. Сейчас мы собираем наше приложение дважды - одна сборка у нас собирается в формате ES5 со всеми требуемыми полифилами, и ещё одна в формате ES2018 с весьма ограниченным набором полифилов.
К вопросу о том, почему остановились на ES2018. Чем выше мы рассматривали версию стандарта, тем меньше чувствовалась разница между сборками разных версий. ES2018 мы выбрали, как некую грань, при которой и 95% пользователей получат быстрый сайт, и при которой будут по максимуму использоваться преимущества современной сборки. Приватных полей в классе мы не держим, так что единственное, в чем будет разница между ES2018 и ES2022 - это потеря в производительности при использовании оператора нулевого слияния и, возможно, логического оператора. Но уж как-нибудь переживем эту потерю.
А теперь о том, как мы это реализовали. Специально для этой статьи я решил создать ещё один репозиторий, в котором показывается, как может быть организована сборка приложения с учетом разделения сборок. В нем я реализовал упрощенную реализацию нашей сборки. Однако, в ней все равно видно как можно организовать не только разделение сборок JavaScript кода, но так же и CSS. Если открыть инструменты разработчика в собранном сайте, видно, что даже на этом небольшом проекте, можно получить сокращение файлов на 120 Кб, что составило в моем случае 30%. Вы можете потрогать ручками деплой сборки из этого репозитория по этой ссылке.
А если вы не хотите смотреть в репозиторий, то я опишу вкратце, каким образом мы определяем на стороне клиента, какую же сборку нужно скачивать. Мы просто проверяем способность браузера к обработке асинхронных функций, а также наличие нескольких полифилов. А затем по флагу window.LEGACY
мы добавляем в head документа скрипт с нужным адресом.
try {
// Polyfills check
if (
!('IntersectionObserver' in window) ||
!('Promise' in window) ||
!('fetch' in window) ||
!('finally' in Promise.prototype)
) {
throw {};
}
// Syntax check
eval('const a = async ({ ...rest } = {}) => rest; let b = class {};');
window.LEGACY = false;
} catch (e) {
window.LEGACY = true;
}
Реальные метрики
Метрики в вакууме - это, конечно, хорошо, но что по реальным метрикам? В конечном итоге мы таки выкатили жесткое разграничение сборок на ES5 и ES2018 на прод. И вот такую разницу в метриках Sitespeed.io мы получили на разных сборках:
First Paint - на 13% быстрее
Page Load Time - на 13% быстрее
Last Visual Change - на 8% быстрее
Total blocking time - на 13% меньше
Speed Index - на 9% быстрее
По большей части эта разница была достигнута за счет меньшего размера скачиваемых файлов. Но в любом случае, переход на ES2018 смог немного повлиять на метрики в лучшую сторону. И самое приятное, что этот выигрыш был получен, почти не трогая исходный код.
Конец
Спасибо за уделенное время. Надеюсь вам, как и мне, было интересно узнать и про производительность, скорость парсинга, и полученные метрики.
Крайне рекомендую посмотреть на репозиторий бенчмарка, о котором я говорил в своей статье. Там помимо приложенных графиков в статье есть ещё "усатые" диаграммы. А ещё в статье я описал не все выводы, которые я получил в своем бенчмарке. Например, мне так же было интересно посмотреть, есть ли разница в производительности браузеров в зависимости от архитектуры и операционной системы. Поэтому я запустил его не только на MacOS, но так же на Windows и Android. И там же я, например, проверял заверения Microsoft об их самом быстром браузере, сравнивая Edge и Chrome.
Так же я ещё раз дам ссылку на репозиторий с примером по организации разделения сборок не только JavaScript но и CSS кода. И в добавок к ней ссылку на GH pages с деплоем этой сборки.
И на этом все. Пишите свои мысли в комментариях, задавайте вопросы. Пока.
То
Комментарии (18)
ko22012
20.06.2023 12:47Не смотря на то, что swc хвалят за производительность, babel наминого интересней в плане поддержки, разных возможности. Тот же hot reload не работает в swc и скорее всего и не будет. Также и интеграции с другими инструментами у babel много. Поэтому для разработки веб приложения выберу babel. Да и babel можно настроить эффективно, чтобы быстрее работал. Т.е. в вебе babel себя зарекомендовал хорошо.
CoolCmd
20.06.2023 12:47+1Помимо трех указанных сборок, я создал еще одну, в которой код тестируемой фичи оставался нетронутым. Её я далее по тексту буду называть современной.
ссылки "Исходный код теста" ведут на файлы ts. а где "нетронутые" файлы js, которые на графиках называются modern?
Yoskutik Автор
20.06.2023 12:47Каждая из 4х версий проходили процесс сборки, в т.ч. и современная. Под "нетронутыми" файлами я подразумевал код, который не был скомпилирован. Т.е. в тесте использования асинхронных функций должен был остаться синтаксис
async
/await
.Вы можете сами посмотреть на собранный код каждой из сборок и убедиться, что в современной версии код фичи остается нетронутым
CoolCmd
20.06.2023 12:47+1ничего не понял. исходный год — ts, и его эти трое транспилируют в js?
Yoskutik Автор
20.06.2023 12:47Да, все верно. Есть исходный код. Его я для удобства решил держать в TS. Исходный код собирается 4 раза в разных конфигурациях. 1 сборка от Babel в ES5, 1 от SWC в ES5 и 1 от TypeScript в ES5.
Ещё одна сборка - modern - должна быть в ES2022. Её я компилировал при помощи SWC. Т.к. собиралась она под ES2022, можно было использовать любой из 3х инструментов, если их правильно настроить. И я решил использовать SWC.
Единственное, для чего используется сборщик в modern сборке - это конвертация кода в JS.
CoolCmd
20.06.2023 12:47зачем на графиках указана opera? у нее двигло тоже самое, что и у chrome.
Yoskutik Автор
20.06.2023 12:47+2На случай, если вам было интересно, будет ли наблюдаться разница между различными V8 браузерами. Да и все-таки Opera это надстройка над Chromium, не совсем уж клон Chrome.
disappearedstar
20.06.2023 12:47+2Я из платформы ozon.ru, мы компилимся в es5. Недавно катнули на полчаса в прод билд на es2018 и не увидели изменений в перфоманс метриках, кроме очевидного уменьшения js transfer size.
По поводу статьи. Почему нет сравнения var vs let/const? Например, в typescript выяснили, что переключение на var может улучшить производительность компилятора из-за отсутствия проверок TDZ.
Добавлю про разницу в генерируемом коде. Некоторые фичи языка можно скомпилить по разному: в код, максимально строго соответствующий спецификации (strict), или в упрощенный код, который покрывает большую часть реальных кейсов, но может работать некорректно в редких/нестандартных ситуациях. У babel во многих трансформирующих плагинах есть опция loose, которая как раз позволяет включить упрощенный режим. Также можно точечно настраивать через assumptions. Например, с помощью флага ignoreFunctionLength можно устранить разницу в эмите tsc и babel в примере со стрелочной функцией. У typescript фичи языка компилятся то в strict, то в loose код, и это не настраивается, кроме, пожалуй, флага useDefineForClassFields; а в TS 4.5 они сделали breaking change и стали более строго компилить шаблонные строки.
Yoskutik Автор
20.06.2023 12:47+1Наверное все зависит от того, как вы считываете метрики. Если transfer size был снижен, значит уже из-за этого метрики могут стать ниже, т.к. пользователь просто напросто быстрее скачает файлы для отображения сайта.
Про разницу генерируемого кода замечание верное. Но если бы я рассматривал матрицу компиляторов со всеми их возможными конфигурациями, бенчмарк и статья бы разрослись раз в 20.
И по поводу let/const. Наверное, да, вы правы. Для более полноценной картины и их следовало добавить. Просто мне показалось, что let и const это совсем уж минорные синтаксические различия. Которые ещё и могут быть изменены минификаторами.
0UTS1D3R
Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик!
Yoskutik Автор
Можно вот этого вот почаще)
Pab10
Hidden text