Как стать автором
Обновить

Оптимизация загрузки js бандла использующего icon pack’и

Время на прочтение3 мин
Количество просмотров2.6K

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

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

На скриншоте видно, что это приложение, состоящее из 2х элементов, весит 722kb. Но почему?

Исходные данные

Давайте посмотрим на код, в котором и находится проблема.

Вроде все просто. У иконки по пропсу name мы понимаем, какую именно иконку из пака нам нужно достать. Но бандл слишком много весит, тут же только одна иконка, почему так? Давайте посмотрим, что происходит внутри компонента иконки.

./components/Icon
./components/Icon

Тут видно, что виной раздувания бандла является fontawesome и его наборы пакетов: free-regular-svg-icons, free-brands-svg-icons, free-solid-svg-icons, и т.д.

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

Теперь взглянем на результаты анализа бандла.

602 kb сжатых gzip данных мы заставляем грузить наших пользователей только для того, чтобы показать им одну иконку! С этим точно нужно что-то сделать.

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

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

Решение

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

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

В рабочем проекте были куплены расширенные пакеты fontawesome, кол-во иконок в них было примерно 7-8т шт. Писать мапы для такой кучи иконок однозначно задача не одного дня.

Поэтому был написан скрипт который сделает всю рутинную работы за нас.

Результат работы скрипта iconPackMapsGenerator
Результат работы скрипта iconPackMapsGenerator

Внутри конфиг для его работы.

  • name: название генерируемого файл;

  • lib: путь до папки с файлами иконок;

  • prefix: префикс для названия иконки. Заменяет префикс fa.

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

И переделываем наш компонент Icon не трогая его интерфейс.

components/Icon.tsx
components/Icon.tsx

Вроде все. Что же у нас получилось в итоге?

Давайте вновь посмотрим на бандл.

Как видно, каждая наша иконка помещена в отдельный чанк, и также можно заметить, что размер бандла значительно увеличился. Было 600kb стало 2.01 Mb. Почему так?

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

При ближайшем рассмотрении чанка с компонентом Icon видно что, больше всего места занимают мапы иконок. Но нам нужны эти файлы так как иначе бандлер не поймет что нам нужно создать отдельный чанк под всевозможные иконки. И имея мапу можем создавать ts-типы для названий всех иконок.

А что же происходит теперь в браузере?

Теперь при загрузке страницы мы видим, что последний чанк размером 1.1kb это наша иконка.

При первой загрузки в начальном варианте мы загружали 722kb, а сейчас 89kb! Уже победа. Помимо этого мы получили:

  1. Сохранение обратной совместимости с исходным проектом;

  2. Динамическая загрузка иконок по требованию;

  3. Возможность добавлять кастомные иконки

Заключение

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

Также если вам интересно в своем Telegram я время от времени выкладываю интересные находки по фронтенду. И всем легких бандлов.

Теги:
Хабы:
+9
Комментарии5

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн