Перейти к содержимому

Объединение и сжатие стилей и скриптов - включение, исключения, поломки

Включаем штатное объединение и сжатие статики, а потом разбираем, что после этого перестало работать на витрине и где искать исходники правок.

Решение

Где включается объединение

Смотрим текущее состояние флагов оптимизации:

// настройки продукта - настройки модулей - главный модуль, раздел оптимизации
echo COption::GetOptionString('main', 'optimize_css_files', 'N'), "\n";
echo COption::GetOptionString('main', 'optimize_js_files', 'N'), "\n";
// рядом в форме живут ещё два флага: минифицированные версии и сжатая копия
// перемещение JS в конец страницы - отдельный флаг с другими последствиями

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

Куда попадают собранные файлы

Находим собранный набор на диске:

Окно терминала
ls /home/bitrix/www/bitrix/cache/css/s1/
# s1 - идентификатор сайта, дальше каталог страницы или шаблона
head -5 /home/bitrix/www/bitrix/cache/css/s1/main/kernel_main/kernel_main.css
# начало набора перечисляет исходники, из которых он склеен

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

Как подключать свои файлы

Регистрируем файлы средствами платформы:

use Bitrix\Main\Page\Asset;
Asset::getInstance()->addCss(SITE_TEMPLATE_PATH . '/css/shop.css');
Asset::getInstance()->addJs(SITE_TEMPLATE_PATH . '/js/shop.js');
// файлы style.css и script.js рядом с template.php платформа подхватит сама

В объединение попадает только то, что зарегистрировано платформой на сервере. Тег в разметке и клиентская загрузка через BX.loadScript проходят мимо сборки всегда, поэтому такие файлы остаются отдельными запросами.

Как исключить отдельный файл

Разводим свой код по отдельному префиксу пути:

/local/js/custom_crm/crm.js - свой префикс, файл живёт отдельным запросом
/local/js/custom/crm.js - общий префикс, файл уедет в общий набор
// каталог /bitrix/js/ под свой код не годится: его перезапишет обновление

Уникальный префикс пути выводит файл из общего набора. Исключение нужно тяжёлым сторонним библиотекам и виджетам, которые ломаются при склейке с чужим кодом или меняют поведение от соседства.

Что ломается после включения

Проверяем, отдаёт ли сервер каталог наборов:

Окно терминала
curl -sI https://example.com/bitrix/cache/css/s1/main/kernel_main/kernel_main.css | head -1
# ответ 404 или 403 означает, что правила веб-сервера не пускают к каталогу кэша

Сайт «в один столбик» после переноса на другой сервер - это почти всегда закрытый доступ к каталогу собранных файлов, а не потерянные стили шаблона.

Минифицированные версии подставляются молча: когда рядом с style.css лежит style.min.css, на страницу уйдёт второй файл. Правка исходника при этом не видна, и сжатую версию приходится пересобирать после каждого изменения.

Порядок внутри набора не обязан повторять порядок подключения. Свои переопределения после включения объединения проверяют отдельно: спор правил равной силы решает положение в собранном файле, а не в исходном коде страницы.

Перемещение JS в конец страницы ломает встроенный код шаблона, который вызывает функции из подключённых файлов. Ошибка вида is not a function появляется через раз и зависит от порядка загрузки на конкретной странице.

Проверка результата

Считаем запросы за статикой до и после включения:

Окно терминала
curl -s https://example.com/ | grep -coE '<(link|script)[^>]+(\.css|\.js)'
curl -s https://example.com/ | grep -oE '/bitrix/cache/(css|js)/[^"?]+' | sort -u
# второй список показывает, какие наборы платформа собрала на этой странице

Разбор поломки начинают с выключенного объединения: тогда в исходном коде видны настоящие пути к файлам. После правок кэш статики сбрасывают, иначе страница продолжит отдавать прежний набор.

Типичные проблемы

После включения объединения сайт отображается в один столбик.

Веб-сервер не отдаёт каталог собранных наборов, и стили не доходят до браузера. Правила обработки объединённых CSS и JS проверяют на стороне сервера.

Правка стилей не видна, хотя файл сохранён.

Рядом с исходником лежит минифицированная версия, и платформа подключает именно её. Сжатый файл пересобирают заново после каждой правки исходного файла.

В инспекторе браузера один общий файл вместо путей к исходникам.

Объединение склеило стили шаблона и компонентов в общий набор кэша. Исходники перечислены комментарием в начале собранного файла, читать нужно его.

Скрипт падает с ошибкой о неизвестной функции через раз.

Перемещение JS вниз отправило библиотеку ниже встроенного кода шаблона. Встроенный вызов переносят в отдельный файл или откладывают до загрузки страницы.

Собранный файл не обновился после правки исходника.

Страница отдана из кэша, и ссылка на прежний набор осталась в разметке. Кэш сбрасывают после правок: метка версии меняется вместе с содержимым.

Частые вопросы

Какие именно файлы будут объединяться?

Только зарегистрированные платформой: стили и скрипты шаблона сайта, шаблонов компонентов и расширений ядра. Файлы, вставленные тегом прямо в разметку, остаются отдельными запросами и в набор не попадают.

Как найти нужный css-файл при включённом объединении?

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

Стоит ли выключать оптимизацию насовсем ради удобства правок?

Нет, это переносит лишний вес на посетителей ради удобства разработчика. Объединение отключают на время разбора и возвращают обратно вместе со сбросом кэша.

Почему приоритет остаётся у минифицированного файла?

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

Как исключить из объединения один тяжёлый скрипт?

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

Смежное

Первоисточник