Представим ситуацию, что вы подняли сайт на Magento 2. Уже собираетесь запустить его, но вдруг замечаете, что он как-то медленно грузится… Вы идете в DevTools и видите, что сайт грузит просто громадное количество JS-файлов. И после небольшого анализа выясняется, что все не очень хорошо. А если конкретно, то на базовой теме Luma вот такая картина:
- домашняя страница грузит 188 JS-файлов;
- каталог продуктов — 189 файлов;
- страница продукта — 201 файл;
- страница оформления заказа (Checkout) — 426 файлов.
Видимо, надо собирать эти файлы в пакеты, чтобы не заставлять пользователя ждать последовательной загрузки каждого из них. Как?
Давайте погуглим. Первая же ссылка ведет нас на официальную документацию JavaScript Bundling. Здесь предлагается собирать весь имеющийся JS в пакеты, которые будут грузиться на всех страницах. С одной стороны, вроде бы решение простое и подходит нам. Можно настроить браузерное кэширование для этих бандлов и, скачав их один раз, больше JS скачивать не понадобится. С другой же стороны, эти пакеты могут содержать много ненужных скриптов, которые не используются (т.к. вы просто не используете ту функцию Magento).
При первом открытии пользователю придется скачивать весь этот пак, а это может быть и больше 10 МБ. Таким образом мы получим выигрыш для серфинга по сайту и последующих входов, но увеличим время первого открытия сайта. При медленном интернете пользователь может не дождаться открытия страницы и уйти с сайта.
Пробуем искать ответ дальше.
Открываем следующую ссылку и здесь — Advanced JavaScript Bundling. По описанию выглядит довольно сложной штукой — много действий, скриптов — от описания больше вопросов, чем ответов. Но на деле, если разобраться — все прекрасно можно реализовать.
Ниже я постараюсь описать, как настроить Advanced Bundling в Magento и какие сложности при этом могут возникнуть.
Принцип работы Advanced Bundling
Нам нужно собрать списки JS-скриптов для каждой из страниц Magento сайта. Затем выделить из них общие скрипты, которые используются везде, и оформить их отдельным списком. Дальше мы создаем конфиг для библиотеки r.js (RequireJS Optimizer) и она собирает для нас эти бандлы. Загружая бандлы на страницах, мы предугадываем зависимости скриптов.
По сути в этом и есть экономия времени — мы не ждем, пока все запросы на зависимости и зависимости зависимостей будут удовлетворены. Они уже заранее будут загружены.
Собираем списки JS-скриптов
В официальной документации описан способ создания списков при помощи PhantomJS. Если вы внимательно прочитали документацию, то сможете найти кусок кода, который вам позволит получить все JS-ы на странице непосредственно из браузерной консоли.
А вот и этот код:
Object.keys(window.require.s.contexts._.defined);
Дальше вам нужно проработать полученный список, изучить документацию и преобразовать его в формат, понятный библиотеке r.js
.
Еще вариант — использовать инструмент, который сделает все это за вас. Для упрощения работы со сбором и преобразованием списков удобней всего использовать браузерное расширение Magento 2 DevTools, доступное на GitHub. Правда, оно уже три года не обновлялось, но все работает. Таким образом можно значительно упростить себе задачу.
Запускаем Magento 2 DevTools
Для того, чтобы запустить Magento 2 DevTools, вам нужно выполнить следующие действия:
1. Клонируем репозиторий к себе на компьютер:
git clone https://github.com/magento/m2-devtools.git
Git у вас должен быть уже установлен, если нет — читаем туториал.
2. Собираем расширение:
npm install npm run-script build
Если npm и Node.js у вас не установлены, то почитайте тут, как их установить. Вам они всегда пригодятся в других задачах. Например, через npm можно устанавливать полезные для разработчика программы и утилиты.
3. Подключаем расширение в браузер. Я это делал в Chrome вот так:
- открываем страницу расширений chrome://extensions/ ;
- включаем Developer Mode (справа переключатель);
- нажимаем кнопку Load unpacked и выбираем папку Extension в папке клонированного ранее репозитория;
- расширение появляется в Chrome.
Далее переходим на ваш Magento-сайт, но на ту версию, на который вы сможете оформить заказ. Открываете Chrome Developer Tools (кнопка F12 или Command+Option+J для Mac), находите в нем новую вкладку Magento 2, в меню ниже выбираете пункт меню RequireJS и нажимаете кнопку записи.
Расширение начинает записывать все JS, доступные на загруженных в этой вкладке страницах. Проходите все типы страниц сайта. То есть вам не нужно открывать прямо все продукты и категории. Достаточно один раз показать расширению, какая у вас категория и продукт, и оно запомнит все загруженные JS-файлы.
Настраиваем сборку
Когда вы попадете на Thank you page (страница с номером заказа после его оформления), расширение закончит свою работу. Сохраните полученный от него конфиг в корень сайта в файл build.js
. Установите r.js
на сервер, где у вас происходит сборка сайта:
npm install -g requirejs
Сразу после сборки статики вашего сайта добавьте следующие строки в деплоймент-скрипт (после команды php bin/magento setup:static-content:deploy
):
mv ./pub/static/frontend/<Vendor>/<theme-name>/en_US ./pub/static/frontend/<Vendor>/<theme-name>/en_US_source r.js -o build.js baseUrl="pub/static/frontend/<Vendor>/<theme-name>/en_US_source" dir="pub/static/frontend/<Vendor>/<theme-name>/en_US/"
Только не забудьте заменить <Vendor>
, <theme-name>
и en_US
на название вашего вендора, темы и язык. В этих двух строках происходит переименование собранной ранее темы в статике (дописывается _source
) и копирование с помощью r.js-файлов из переименованной темы в оригинальную. При этом происходит сборка бандлов согласно конфигурации в build.js
.
Подключаем бандлы к сайту
В том же репозитории, откуда мы брали браузерное расширение, есть и специальный модуль Magento BundleConfig. Его достаточно установить в app/code
, пройдя весь процесс установки, и ваши бандлы начнут загружаться. Теперь вместо сотен отдельных JavaScript-файлов у вас будут загружаться бандлы.
Проблемы с JavaScript mixins
Если вы используете старую версию Magento, которая ниже 2.3.6, то скорее всего у вас будут проблемы с загрузкой *-mixin.js
. Эти файлы расширяют функционал JS-компонентов в Magento. Из-за этого некоторый функционал может сломаться. Особенно это будет видно на странице Checkout.
Случиться может что-угодно: начиная от некорректной работы платежа и заканчивая появлением белого экрана, когда вообще ничего не работает на странице.
Чтобы решить проблему, вам нужно скачать исправленный mixins.js
из репозитория Magento по этой ссылке и положить его в тему:
app/design/frontend/THEME_VENDOR/THEME_NAME/web/mage/requirejs/mixins.js
Если кому-то интересны детали, посмотрите Pull Request c исправлением по этой ссылке.
А что же дальше?
Вот вы и настроили Advanced Bundling, все работает хорошо, сайт летает. Но что делать дальше, как поддерживать бандлы актуальными? Ведь разработка нового функционала продолжается, а после обновлений Magento появляются новые JS-файлы. Мы в своей команде решаем это так:
- Если вы сами добавляете какой-то JS-файл в проект, то можете его дописать в конфиг
build.js
. Он имеет довольно простую структуру, и это не составит особого труда. - На случай масштабных изменений можно всегда заново пройтись уже собранным браузерным расширением.
На самом деле нет ничего страшного, если несколько файлов не будут добавлены в бандл. Они просто будут загружаться отдельно, и это в целом не испортит картину производительности сайта. Если кто-то сталкивался с более оптимальным решением задачи актуальности бандлов — было бы интересно почитать о вашем опыте в комментариях.
P.S. Источники моей статьи — официальная документация и это видео:
Читайте также: Как я разгоняю интернет-магазины до сверхзвуковой скорости и вывожу в топ Google: 19 советов бэкендера
Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: