- PVSM.RU - https://www.pvsm.ru -
Сейчас популярно мнение, что текущие Javascript-фреймворки непомерно большие, а новый фреймворк Svelte [1] очень компактный. Поэтому всем нужно переходить на него, и проблема размера Javasctipt решится сама собой.
Недавно вышла статья "Хороший ли выбор Svelte для реализации виджета?" [2] с опытом реализации проекта с критичным размером бандла. Это отличный повод проверить обещания пиарщиков Svelte на реальном проекте.
Давайте его проанализируем!
Рассматриваемый проект – это встраиваемый виджет, распространяется как монолитный Javascript-бандл общим размером в 71 Кб (c учётом gzip). Много это или мало? В статье "Цена JavaScript в 2019 году" [3] была рекомендация избегать бандлов больше 50-100 Кб. То есть текущий проект находится в жёлтой зоне, размер ещё приемлемый, но уже пора задуматься, о том как в него добавить новой функциональности, и при этом уместиться в верхний лимит в 100 Кб.
Теперь скачаем [4] этот скрипт, отформатируем его и посмотрим, что там интересного.
Первое, что бросается в глаза при просмотре кода – повторение вот такого паттерна:
function (t, e, n) {
t.exports = {
// какой-то код
}
}
Это очень похоже на CommonJS модуль. Однако в современных проектах рекомендуется [5] использовать ES-модули, потому что этот формат обеспечивает возможность для оптимизаций – Scope hoisting [6] и Tree-shaking [7]. В случае CommonJS-модулей, бандлеры оптимизировать их не могут и выдают больше кода на выходе.
Иногда ещё может получиться так, что вы используете ES-модули в своем коде, а бандл все равно выходит не оптимизирован. В этом случае полезно запустить webpack с флагом --display-optimization-bailout [8] и посмотреть, что пошло не так с оптимизациями.
Неправильно настроенный бандлер может разрушить всю "магию исчезновения" [9] Svelte, которая целиком основана на описанных выше оптимизациях, поэтому в случае ошибок в конфигурации к вам в бандл попадёт весь фреймворк целиком.
К сожалению, у меня нет доступа к исходному коду, поэтому посмотреть на их настройки не получится, но по моему опыту правильно настроенные оптимизации позволяют сократить бандл на 20%, сбросив 14 Кб из общего размера виджета.
Далее мы замечаем, что в бандл включены SVG и JPG изображения. Очень важно, чтобы для веба ресурсы были правильно оптимизированы и весили как можно меньше.
Начнем с SVG. Для его оптимизации есть инструмент SVGO [10], также доступна онлайн-версия [11].
Всего в бандле нашлось 7 svg-файлов общим весом в 10 Кб, и, по-видимому, разработчики не занимались их оптимизацией. Пропустив их через SVGO удалось уменьшить общий размер на 3 килобайта.
Теперь про JPG. Заметим, что картинки загружаются в блок размером 59х27 пикселей, а сами оригиналы 183x72. Избыточный размер, даже с учетом поддержки retina-экранов. Кроме того, есть шансы улучшить размер подбором более оптимальных форматов сжатия. Очень удобно это делать в веб-приложении https://squoosh.app/ [12], которое позволяет пережать изображения прямо в браузере с использованием различных кодеков. Применив его к картинкам из виджета, сокращаем их размер на треть, получая еще 7 килобайт экономии.
Чтобы не тратить время на оптимизацию каждого изображения вручную, рекомендуется добавить процесс оптимизации в свою сборку, SVGO [10] уже упоминался выше, а для растровых картинок есть imagemin [13].
Теперь переходим к разбору собственно Javascript. Там встречается нетранспилированный ES6-код, а значит поддержка IE от разработчиков не требовалась. И это действительно хорошая стратегия уменьшить размер кода – по моим данным, использование ES6 сокращает размер кода на 7%. Если вам не нужно поддерживать Internet Explorer, это может оказаться очень хорошим подспорьем.
Далее обратим внимание на используемые библиотеки.
process.env.NODE_ENV
, и добавляет полноразмерный полифилл для process
вместо одного только объекта process.env
. Избавление от этого модуля сэкономит нам еще 1 килобайт.Еще полезно прогнать код через Code Coverage [18] из Chrome Devtools. Для этого виджета инструмент показывает, что 24% Javascript не используется. Это не обязательно означает, что весь неиспользуемый код можно удалить, возможно, он нужен для обработки ошибок и других пограничных случаев, но это хороший сигнал обратить на него внимание и подумать, а зачем этот код вообще нужен.
Итого, оптимизации позволили бы сократить размер этого виджета на 46 килобайт (более чем в 2 раза!)
Таким образом, мы видим, что на размер бандла влияет множество факторов, и эффект от использования Svelte примерно как от запивания гамбургера диетической колой – исключительно психологический. Реальная оптимизация требует внимания к деталям и контролю размера на выходе.
А если вы задумываетесь о переходе на Svelte ради уменьшения размера своего проекта – советую обратить внимание на пункты выше, возможно, если их исправить, то никуда переходить и не понадобится.
Автор: Борис Сердюк
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/353516
Ссылки в тексте:
[1] Svelte: https://svelte.dev
[2] "Хороший ли выбор Svelte для реализации виджета?": https://habr.com/en/company/citymobil/blog/504270/
[3] "Цена JavaScript в 2019 году": https://habr.com/en/company/ruvds/blog/459296/
[4] скачаем: https://widget.city-mobil.ru/bundle.js
[5] рекомендуется: https://webpack.js.org/api/module-methods/#es6-recommended
[6] Scope hoisting: https://medium.com/webpack/brief-introduction-to-scope-hoisting-in-webpack-8435084c171f
[7] Tree-shaking: https://webpack.js.org/guides/tree-shaking/
[8] --display-optimization-bailout: https://webpack.js.org/plugins/module-concatenation-plugin/#debugging-optimization-bailouts
[9] "магию исчезновения": https://habr.com/en/post/345028/
[10] SVGO: https://github.com/svg/svgo
[11] онлайн-версия: https://jakearchibald.github.io/svgomg/
[12] https://squoosh.app/: https://squoosh.app/
[13] imagemin: https://github.com/imagemin/imagemin
[14] axios: https://github.com/axios/axios
[15] process: https://github.com/defunctzombie/node-process
[16] sentry: https://docs.sentry.io/platforms/javascript/
[17] не рекомендуется: https://habr.com/en/company/ruvds/blog/483682/
[18] Code Coverage: https://developers.google.com/web/tools/chrome-devtools/coverage
[19] Источник: https://habr.com/ru/post/504612/?utm_source=habrahabr&utm_medium=rss&utm_campaign=504612
Нажмите здесь для печати.