Когда в последний раз вы проверяли размер JavaScript-бандлера?

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

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

Если вы когда-нибудь испытывали раздражение, ожидая загрузки сайта, или замечали, что начальный рендеринг вашего приложения кажется медленным на мобильном устройстве, то виной тому может быть раздутый JS-бандлер.

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

Сегодня вплотную подойдем к решению этой проблемы.

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

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

Почему тяжелый бандлер вреден 

Для начала выясним, почему большой бандлер вообще является проблемой.

Вы можете возразить: «Современные браузеры работают быстро, разве нет?». Конечно, но учтите, что не все ваши пользователи работают на новейших MacBook с оптоволоконным интернетом. Многие используют мобильные устройства с нестабильным соединением. Каждый лишний бит данных означает увеличение времени ожидания, прежде чем что-то появится на экране.

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

И дело не только в скорости — производительность влияет на все. Поисковые системы используют производительность как фактор ранжирования.

Неповоротливый сайт кажется низкопробным и недоработанным.

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

Шаг 1. Аудит зависимостей

Скорее всего, вы импортируете библиотеки, которые не используете в полной мере.

Возможно, импортировали тяжелую библиотеку диаграмм для одного небольшого графика. Может быть, UI-фреймворк загружает все доступные компоненты, даже если нужны всего два.

Первый шаг к избавлению от лишней нагрузки — узнать, что входит в состав бандлера. Используйте такие инструменты, как webpack-bundle-analyzer или Source Map Explorer.

Выявив крупного виновника расходов, подумайте: действительно ли нужна эта библиотека? нельзя ли ее заменить ее более легкой альтернативой?

Иногда сэкономить сотни килобайт можно, просто перейдя с тяжелого UI-набора на модульную библиотеку компонентов или используя встроенные API браузера вместо большой библиотеки полифиллов.

Шаг 2. Разделение кода и ленивая загрузка

Универсальный принцип («единый для всех размер»), подходящий для производителя футболок, не годится для бандлеров.

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

Такие инструменты, как Webpack, Parcel или esbuild, обеспечат вам это.

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

Шаг 3. Встряска дерева вызовов и устранение «мертвого» кода

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

Если код и зависимости структурированы корректно (например, с использованием ES-модулей), бандлер может определить, какие функции или компоненты действительно используются, и выбросить все остальное.

Кроме того, выполните процедуру по устранению «мертвого» (неработающего) кода. Удалите устаревшие функции, старые эксперименты, которые вы закомментировали несколько месяцев назад, и все утилиты, которые больше не вызываются.

Каждая строчка кода имеет значение.

Шаг 4. Оптимизация и минификация кода

Минификация и сжатие кода — самое очевидное из того, что нужно сделать. Такие инструменты, как Terser, сокращают имена переменных и удаляют пробельные символы. Сжатие с помощью Gzip или Brotli на уровне сервера сокращает код при передаче по сети.

При этом функциональность не меняется — только способ упаковки и доставки кода.

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

Иногда переход с Gzip на Brotli (если он поддерживается) может дать удивительную разницу.

Шаг 5. Рассмотрение альтернатив тяжелой работе на стороне клиента

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

Если это так, рассмотрите возможность переноса части логики на сервер. Рендеринг на стороне сервера (SSR) или статическая генерация сайтов (SSG) могут переложить большую часть вычислений на сервер, что приводит к уменьшению нагрузки на JS для пользователя.

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

Если SSR или SSG — слишком резкое изменение, обратите внимание на фреймворки с частичной гидратацией или подумайте о том, чтобы переложить некоторые тяжелые вычисления на веб-воркер.

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

Почему все это важно

Итак, вы приложили усилия. Почему они так важны?

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

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

Производительность также связана с доступностью. Пользователи с медленным соединением получают огромную пользу от более легкого бандлера.

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

Если задуматься, то эффективность — один из основных столпов продвинутой инженерии.

Уменьшение размера бандлера демонстрирует ваше мастерство. Оно показывает, что вы заботитесь о своей аудитории и уважаете ее время и ресурсы.

Подведение итогов

JavaScript-бандлер не обязательно должен быть раздутым. С помощью нескольких стратегических изменений — аудита зависимостей, разделения кода, встряски дерева вызовов, оптимизации и пересмотра способа доставки контента — можно сделать сайт быстрым и удобным для пользователей.

Пользователям безразлично, сколько библиотек вы используете. Им важны скорость и отзывчивость.

Уделив время уменьшению объема JS-бандлера, вы не просто повысите производительность — вы создадите лучшую, более дружелюбную среду для своей аудитории. В конечном итоге именно в этом и заключается назначение веб-разработки.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Yuri Bett: Your JavaScript Bundle Is Too Fat

Предыдущая статьяПочему все говорят о Zig?
Следующая статьяC++: полное руководство по memset