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

Композитный сайт - настройка, сброс кеша и диагностика

Устройство композита и адаптация шаблонов разобраны в статье Композитный сайт. Здесь - эксплуатационная сторона: режимы и хранилище, управление кешем из кода и по расписанию, работа JS в композитном режиме и диагностика.

Как это работает

Порядки величин, ради которых всё затевается. Первый пользователь получает страницу примерно за 750 миллисекунд - она генерируется обычным образом. Последующие получают готовый HTML примерно за 15 миллисекунд. Ускоряется только время ответа сервера: загрузка стилей, скриптов и изображений остаётся прежней.

Два режима настройки. Автокомпозит сам расставляет параметры: голосование шаблонов, автоматические динамические области, режим перезаписи с задержкой - этого достаточно простым сайтам. Ручной режим даёт настройку каждого компонента и нужен на сложных проектах.

Хранилище кеша - файлы или memcached. Файлы занимают больше места, но надёжнее и вытесняются по давности использования. Memcached быстрее, но теряется при перезагрузке сервиса.

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

Примеры

1. Управление кешем из кода

use Bitrix\Main\Data\StaticHtmlCache;
// сбросить весь статический кеш
StaticHtmlCache::getInstance()->deleteAll();
// запретить кеширование текущей страницы - можно вызвать из любой её части
StaticHtmlCache::getInstance()->markNonCacheable();

Второй метод удобен для страниц, которые принципиально персональны: личный кабинет, оформление заказа, результаты поиска с параметрами.

2. Сброс по расписанию

Окно терминала
# удалить файлы композитного кеша старше 10 часов
php -f /path/to/site/bitrix/modules/main/tools/cron_html_pages.php 10

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

3. Ветвление JavaScript

if (window.frameCacheVars !== undefined) {
BX.addCustomEvent('onFrameDataReceived', function (json) {
// страница пришла из композита, данные динамических зон получены
initBasketCounter();
});
} else {
BX.ready(function () {
// обычная загрузка
initBasketCounter();
});
}

Это главный приём для фронтенда на композитном сайте. Инициализация, повешенная только на готовность документа, в композите выполнится до прихода реальных данных, и вы увидите «моргание» или пустые значения.

4. Условные ресурсы динамической области

$dynamicArea = new \Bitrix\Main\Page\FrameStatic('workarea');
$dynamicArea->setAssetMode(AssetMode::STANDARD); // ресурсы исключаются из кеша
$dynamicArea->setStub('заглушка');
$dynamicArea->startDynamicArea();
$APPLICATION->includeComponent('mycompany:mycomponent', 'template', []);
$dynamicArea->finishDynamicArea();

Так подключают стили и скрипты, которые нужны только части пользователей, не ломая статический кеш. Прямое условное подключение в секции head этот кеш перезаписывает.

<script>
if (document.cookie.indexOf('my_cookie=yes') >= 0) {
document.documentElement.className += ' has-cookie';
}
</script>
<style>
.block { display: none; }
.has-cookie .block { display: block; }
</style>

Проверка cookie в PHP внутри секции head меняет разметку для разных пользователей и заставляет кеш перезаписываться. Перенос логики на клиент решает проблему полностью: разметка одинакова для всех, а различия делает CSS.

Справочник API

APIНазначениеОсобенности
StaticHtmlCache::deleteAll()сброс всего композитного кеша
StaticHtmlCache::markNonCacheable()запрет кеширования страницывызывается из любой части страницы
cron_html_pages.phpсброс по расписаниюпринимает возраст файлов в часах
FrameStaticдинамическая область на меткахподходит для отложенных функций
setAssetMode()режим подключения ресурсов областиSTANDARD исключает их из кеша, NO_ASSETS не добавляет
setStub()заглушка областипоказывается до подгрузки данных
window.frameCacheVarsпризнак композитного режимаоснова ветвления на клиенте
onFrameDataReceivedсобытие получения данных зонинициализация фронтенда для композита
$this->randString()стабильный идентификаторвместо случайных значений в разметке

Частые ошибки

Скрипты инициализируются не вовремя. Код на готовность документа выполняется до прихода данных динамических зон. Нужно ветвление по признаку композитного режима.

Кеш перезаписывается на каждом запросе. Ищите различающиеся между запросами детали: случайные идентификаторы, проверку cookie в PHP, условное подключение ресурсов, адрес запроса в атрибутах, данные сессии.

Персональные страницы попадают в кеш. Личный кабинет и оформление заказа исключают явно - методом запрета кеширования страницы.

Кеш разрастается. На большом сайте статических страниц много. Ограничивайте их возраст скриптом по расписанию, а не ручной чисткой каталога.

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

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

Как сбросить композитный кеш программно?

Методом deleteAll() у класса статического кеша - он очищает весь кеш целиком. Для точечного случая есть markNonCacheable(): он запрещает кешировать текущую страницу и вызывается из любой её части, в том числе из компонента. На больших сайтах дополнительно настраивают удаление старых файлов скриптом по расписанию.

Почему JS-код работает неправильно при включённом композите?

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

Файлы или memcached для хранения композитного кеша?

Файлы надёжнее: кеш переживает перезапуск сервисов, а вытеснение идёт по давности использования. Memcached быстрее, но всё содержимое теряется при перезагрузке, и после неё сайт какое-то время работает без композита. На одиночном сервере обычно берут файлы, в кластере выбор зависит от того, как организовано общее хранилище.

Как исключить из композита личный кабинет?

Вызовом запрета кеширования страницы - это надёжнее, чем полагаться на голосование компонентов. Заодно имеет смысл исключить из композита группу администраторов: админ-панель кешировать не нужно, а лишние перезаписи кеша она провоцирует.

Связанные темы

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