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

Стили и скрипты в шаблоне - подключение, порядок, кэш

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

Решение

Подключаем файлы средствами платформы:

global $APPLICATION;
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . '/css/shop.css');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH . '/js/shop.js');
Asset::getInstance()->addJs(SITE_TEMPLATE_PATH . '/js/cart.js');
// на сайте с несколькими шаблонами путь считается от текущего шаблона
// путь всегда от каталога шаблона: относительные пути ломаются на внутренних
// повторное подключение того же файла платформа отбрасывает сама

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

Разбираемся с порядком загрузки:

// стили шаблона подключаются первыми, свои - после них
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . '/css/theme.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . '/css/overrides.css');
// правило из файла ниже перекрывает правило из файла выше при равной силе

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

Включаем объединение файлов:

// настройки главного модуля: объединение CSS и JS
echo COption::GetOptionString('main', 'optimize_css_files', 'N'), "\n";
echo COption::GetOptionString('main', 'optimize_js_files', 'N'), "\n";
// объединение работает только для файлов, подключённых средствами платформы

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

Проверяем, что браузер получил свежий файл:

Окно терминала
curl -s https://example.com/ | grep -oE '/bitrix/cache/css/[^"]+' | head -3
# в имени собранного файла есть метка версии: она меняется при правке исходников
// личные блоки шапки помечают динамическими областями до включения композита

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

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

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

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

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

Один и тот же файл подключён дважды.

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

Свои стили не перекрывают стили шаблона.

Файл подключён раньше перекрываемого. При равной силе правил побеждает подключённый последним.

Объединение включено, а файлов по-прежнему много.

Часть файлов подключена тегом в разметке. В сборку попадает только зарегистрированное платформой.

Посетители видят старую версию скрипта.

Файл подключён без метки версии. Браузер держит его в кэше до истечения срока, заданного сервером.

После обновления сломалась разметка.

В шаблоне лежит своя копия библиотеки платформы. Штатные компоненты рассчитаны на версию из платформы, а не на копию.

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

Чем стили шаблона отличаются от стилей компонента?

Шаблон компонента подключает свой файл сам, и платформа добавляет его в общую сборку. Стили шаблона сайта подключают явно.

Где хранить свои скрипты?

В каталоге шаблона сайта или в своём модуле. Каталоги штатных модулей для этого не годятся: обновление их перезапишет.

Всегда ли включать объединение файлов?

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

Нужно ли объединение при современном протоколе?

Выигрыш меньше, чем раньше, но остаётся: меньше файлов - меньше накладных расходов. Начинать всё равно стоит с размера самих файлов.

Смежное

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