- PVSM.RU - https://www.pvsm.ru -

Ломать — не строить. Или Devolution

В последнее время на Хабре появилось пара интересных статей. Первая была посвещена проблеме минификации ES6 [1], вторая про общие полезные советы оптимизации webpack [2].

Все бы хорошо, но они обе обошли стороной вопрос разделение бандлов на ES6 и ES5 для целей минификации и другой оптимизации. И вообще, в то время как одни все пишут и пишут статьи про это [3] — другие (почти все) данную технику игнорируют.

Потому что Долго. Дорого. И не так чтобы очень очень.

А надо быстро, дешево, и потупее. Возможно следует просто обратить эволюцию вспять.

Ломать — не строить. Или Devolution - 1

Идея

Описывать «идею» — не самая лучшая идея. Лучше описать то, как она должна работать. То как процесс формирования бандла должен работать:

  • у меня есть код
  • я его компилирую под мой «разработческий» браузер
  • и оно все работает.

Разработческий браузер тут — так чтобы async/await, generator, classes, arrow functions и так далее. В общем target: esmodules в бабеле.

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

И именно это надо исправить.

Devolution

Devolution [4] — маленькая cli утилитка, которая возьмет ваш бандл, скомпилированный в target: esmodules, и деградирует его до es5, добавив все нужные полифилы по пути.

Если вкратце, то:

  • находятся все js скрипты
  • прогоняются через babel с одним активным плагином (форк useBuiltins: «usage»), который определяет требуемые полифилы. Это быстро, так как трансформаций нет.
  • для каждого файла собираются все нужные ему полифилы (минус те, что уже есть в главном бандле), обьединяются, прогоняются через terser и добавляются в начало файла.
  • каждый файл прогонятся через swc, rust версию babel, которая де-модернизирует код до уровня понятному IE11. Работает в 10-60 раз быстрее babel. Он не поддерживает различные плагины, но это и не нужно — все что нужно __уже__ применено.
  • на результат еще раз накладывается terser, но с выключеным mangle(сжатие имен), что опять же — быстро.
  • все это выполняется в воркерах.

Я прогнал код на трех проектах разного уровня сложности:

  • проект 1, 60 конечных js файлов (code-splitting). Время сборки 400s. Devolution 30s.
  • проект 2, 1 конечный js файл (30mb). Время сборки 120s. Devolution 10s.
  • проект 3, 1 конечный js файл (2mb). Время сборки 20s. Devolution 5s (на старте воркеров много что-то да и теряется).

Бонус от ESM бандла получился немного странный:

  • один проект похудел на 400kb babel/polyfill. Банально там не использовалось ничего «сверх» браузерных фишек, и в «esm» их полифилить не надо
  • один проект похудел на 10% из-за сильно более компактного кода генераторов, async/await и конструкторов классов
  • один проект потолстел, так как «loose» babel трансформации иногда делают код более компактным. Но loose mode немного опасная опция, в то время как «ES6» код — «безопасный».

Еще раз:

  • берем ES6 код (точнее esmodule, let/const будут заменены на var в целях скорости)
  • делаем из него ES5
  • докидываем сбоку полифилов
  • раскидываем по папочкам, добавляем симлинки на остальные файлы
  • меняем подключение скриптов на страницы на чуть более умное (IE11 modules/nomodules не понимает)
  • готово — ESM для 85% кастомеров, ES5 для тех кто в танке.

Просто. Быстро. Просто Тупо. Мы де-модернизировали бандл. Старые браузеры! Ау — кушать подано.

Ну а новые браузеры получат бандл почти без полифилов, без страшных трансформаций генераторов и async/await, с arrow functions без бубнов (и они вообще быстрее). В общем все счастливы, вроде так изначально и задумывалось.

github.com/thekashey/devolution [4]

PS: На самом деле в данный момент devolution не использует swc, так как он иногда делает код не очень рабочим — github.com/swc-project/swc/issues/280 [5], Бабель при этом не так чтобы сильно медленнее — там где swc правлялся за 20 секунд, babel справляется за минуту. При времени «нормальной» сборки — от 5ти и далее — это большой плюс

P.S.: Если вдруг стало интересно почему devolution — видео здесь [6].

Автор: Корзунов Антон

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/310129

Ссылки в тексте:

[1] минификации ES6: https://habr.com/ru/company/yandex/blog/438022/

[2] полезные советы оптимизации webpack: https://habr.com/en/company/oleg-bunin/blog/433324/

[3] статьи про это: https://web.dev/fast/serve-modern-code-to-modern-browsers/codelab-serve-modern-code

[4] Devolution: https://github.com/thekashey/devolution

[5] github.com/swc-project/swc/issues/280: https://github.com/swc-project/swc/issues/280

[6] видео здесь: https://www.youtube.com/watch?v=MdrlALQVEKM

[7] Источник: https://habr.com/ru/post/441942/?utm_source=habrahabr&utm_medium=rss&utm_campaign=441942