Большой размер JavaScript файлов в Magento2 - большая проблема, в этой статье мы попробуем Magento Advanced JavaScript Bundling. Рассмотрим инструменты, настройку и работоспособность.
Основная цель JavaScript-бандлинга состоит в том, чтобы уменьшить количество и размер запрашиваемых ресурсов для каждой страницы.
В дефолтной версии бандлинга на каждую страницу подгружается абсолютно весь "набор" сбандленных JavaScript файлов.
То есть, в бандлах на примере выше присутствуют JavaScript файлы чекаута, страницы категорий, продуктовой страницы и прочее, и все это грузится для каждой страницы.
Advanced JavaScript Bundling помогает решить эту задачу, а именно, сформировать бандлы по типам страниц. Например, общий бандл для JavaScript файлов, которые нужны на каждой странице, и отдельные бандлы для чекаута, категории, продуктовой страницы, CMS-страниц и пр.
Звучит красиво, но на деле не все так хорошо, как может показаться.
В официальной документации есть статья, как настроить advanced JavaScript bundling.
В ней предлагается несколько вариантов:
- Ручная настройка - основана на RequireJS optimizer
- Модуль Magento_Baler
Ручной режим
Первый вариант - очень сложный и трудоемкий, подразумевает ручное составление конфигурации под каждый бандл. Поддержка проекта так же очень сильно пострадает.
Для реализации требуется наличие следующих инструментов:
Пример билд-файла можно посмотреть тут
После того, как мы проделали всю кропотливую работу по составлению билд-файла, необходимо выполнить генерацию статики:
php -f bin/magento setup:static-content:deploy -f -a frontend
Далее перенести содержимое статики во временных каталог:
mv pub/static/frontend/Magento/{theme}/{locale} pub/static/frontend/Magento/{theme}/{locale}_tmp
Затем запустить r.js optimizer для файла билд-файла:
r.js -o build.js baseUrl=pub/static/frontend/Magento/{theme}/{locale}_tmp dir=pub/static/frontend/Magento/{theme}/{locale}
Эта команда генерирует бандлы в подкаталог bundles корневого каталога Magento:
pub/static/frontend/Magento/{theme}/{locale}/bundles
total 1900 drwxr-xr-x 2 root root 4096 Mar 28 11:24 ./ drwxr-xr-x 70 root root 4096 Mar 28 11:24 ../ -rw-r--r-- 1 root root 116417 Mar 28 11:24 cart.js -rw-r--r-- 1 root root 187090 Mar 28 11:24 catalog.js -rw-r--r-- 1 root root 307619 Mar 28 11:24 checkout.js -rw-r--r-- 1 root root 1240608 Mar 28 11:24 default.js -rw-r--r-- 1 root root 74233 Mar 28 11:24 shipping.js
Чтобы RequireJS использовал эти бандлы, необходимо добавить onModuleBundleComplete callback в файле build.js:
[ { //... exclude: [ 'requirejs/require', 'bundles/default', 'bundles/checkout', 'bundles/cart', 'bundles/shipping', 'mage/bootstrap' ], }, ], bundlesConfigOutFile: `${config.dir}/requirejs-config.js`, onModuleBundleComplete: function(data) { if (this.bundleConfigAppended) { return; } this.bundleConfigAppended = true; // bundlesConfigOutFile requires a simple require.config call in order to modify the configuration const bundleConfigPlaceholder = ` (function (require) { require.config({}); })(require); `; fs.appendFileSync(this.bundlesConfigOutFile, bundleConfigPlaceholder); }
Далее, запустить команду
r.js -o app/design/frontend/Magento/luma/build.js baseUrl=pub/static/frontend/Magento/{theme}/{locale}_tmp dir=pub/static/frontend/Magento/{theme}/{locale}
Если мы откроем requirejs-config.js в pub/static/frontend/Magento/{theme}/{locale}, то увидим следующее:
require.config({ bundles: { "bundles/default": ["mage/template", "mage/apply/scripts", "mage/apply/main", "mage/mage", "mage/translate", "mage/loader"], "bundles/cart": ["Magento_Ui/js/lib/validation/utils", "Magento_Ui/js/lib/validation/rules", "Magento_Ui/js/lib/validation/validation"] } }
Для "сжатия" бандлов мы можем можем добавить следующую конфигурацию в билд-файле:
({ optimize: 'uglify2', inlineText: true })
Magento_Baler
Модуль Magento_Baler - использует схожие принципы первого метода, но добавляется автоматизация. К сожалению, в данный момент этот модуль находится в стадии раннего alpha-тестирования, не стабилен и содержит в ряд ошибок.
Так же существует ряд сторонних решений:
На данный момент времени нет готового работающего инструмента для реализации этой задачи. Все примеры реализованы на базовой теме Luma, в случае полноценного интернет-магазина на Magento, который, как правило, включает в себя ряд сторонних модулей - нет никаких гарантий оптимальной работы этих модулей при advanced JavaScript bundling.