Композитный сайт в 1С-Битрикс - как работает и как настроить
Композитный сайт - надуровень кеширования: готовый HTML страницы сохраняется и отдаётся почти мгновенно, а персональные блоки подгружаются отдельно. Разберём, как это работает изнутри, как адаптировать шаблоны и почему кеш иногда перезаписывается на каждом запросе. Настройка хранилища, сброс кеша и диагностика на боевом сайте - в статье «Композит: эксплуатация».
Как это работает
Ускоряется только время ответа сервера. Композит не влияет ни на DNS, ни на установку соединения, ни на загрузку картинок и скриптов. Он сокращает именно время генерации страницы - с сотен миллисекунд до примерно пятнадцати.
Механика в два такта. Первый запрос генерирует страницу обычным образом, затем динамические зоны заменяются заглушками, добавляется JS-загрузчик, считается контрольная сумма и HTML пишется на диск. Последующие запросы получают готовый файл сразу, а загрузчик фоновым запросом забирает свежие данные для динамических зон. Сервер пересчитывает контрольную сумму: если она изменилась, кеш обновляется.
Динамическая зона - это кусок шаблона между двумя вызовами. Всё, что
находится между createFrame()->begin() и end(), выполняется на каждом
запросе, а статика вокруг попадает в HTML-файл. Типичные кандидаты: блок
авторизации, строка корзины, просмотренные товары, баннеры, относительное время,
таймеры. Вкладывать зоны друг в друга нельзя.
Компоненты голосуют за кеширование страницы. Компонент, который нельзя
кешировать, вызывает setFrameMode(false) - это голос против. Достаточно одного
неадаптированного шаблона, чтобы композит отключился для всей страницы.
Компоненты внутри динамических областей всегда голосуют за.
Два класса зон. FrameBuffered буферизирует содержимое, но внутри него не
работают отложенные функции вроде вывода заголовка. FrameStatic ничего не
буферизирует: он расставляет метки начала и конца и извлекает контент после
выполнения страницы - им обходят ограничение с отложенными функциями и подключают
условные стили и скрипты.
Два режима настройки. Автокомпозит расставляет параметры сам и включает голосование; ручной режим даёт полный контроль над каждым компонентом и нужен на сложных проектах. Кеш хранится в файлах (надёжнее, с вытеснением по давности) или в memcached (быстрее, но теряется при перезагрузке).
Примеры
1. Динамическая зона в шаблоне компонента
<?php$frame = $this->createFrame()->begin('');?> <div class="basket-line"> Товаров в корзине: <?= $basketCount ?> </div><?php$frame->end();?>
<!-- всё, что ниже, попадёт в статический HTML --><div class="catalog-list">...</div>Аргумент метода begin() - это заглушка, которая покажется до подгрузки реальных
данных. Пустая строка означает пустое место; можно поставить прелоадер или
нейтральный текст.
2. Компонент, который нельзя кешировать
$this->setFrameMode(false); // голос против композита для всей страницыВызов уместен там, где содержимое принципиально персонально и не разбивается на зоны. Но помните цену: одна такая строка отключает композит для страницы целиком. Правильнее сначала попробовать вынести персональную часть в динамическую зону.
3. Что нельзя делать в кешируемом шаблоне
// ПЛОХО: идентификатор сессии, пользователь и время попадут в статический HTMLecho bitrix_sessid_post();echo $USER->GetID();echo date('H:i:s');
// ХОРОШО: те же данные берём на клиенте// BX.message('bitrix_sessid'), BX.message('USER_ID'), BX.message('SERVER_TIME')// ПЛОХО: случайная строка меняет контрольную сумму на каждом хите$id = 'block_' . rand();
// ХОРОШО: стабильная строка, привязанная к компоненту$id = 'block_' . $this->randString();Логика причины одна и та же: любая деталь, которая различается между запросами или пользователями, меняет контрольную сумму - и статический кеш переписывается заново. Тогда композит не ускоряет сайт, а нагружает его.
По той же причине не стоит проверять cookie в PHP внутри секции head: перенесите
логику в JavaScript, повесьте класс на корневой элемент и управляйте показом
через CSS.
Справочник API
| API | Назначение | Особенности |
|---|---|---|
$this->createFrame()->begin() / end() | динамическая зона | вкладывать зоны друг в друга нельзя |
аргумент begin($stub) | заглушка до подгрузки | пустая строка, прелоадер или текст |
$this->setFrameMode(true) | пометка области как кешируемой | вызывается в шаблоне |
$this->setFrameMode(false) | голос против композита | отключает его для всей страницы |
FrameBuffered | буферизирующая зона | внутри не работают отложенные функции |
FrameStatic | зона на метках | подходит для отложенных функций и условных ресурсов |
AssetMode::STANDARD / NO_ASSETS | режим подключения ресурсов зоны | добавлять в секцию head или нет |
$this->randString() | стабильный идентификатор | вместо rand(), не ломает кеш |
BX.message('bitrix_sessid') и подобные | серверные значения на клиенте | вместо PHP-переменных в шаблоне |
/bitrix/html_pages/<домен>/ | хранилище статических страниц | вручную не удалять |
cron_html_pages.php | сброс кеша по расписанию | штатный способ вместо ручной чистки |
Частые ошибки
Ждут ускорения всего подряд. Композит сокращает только время ответа сервера. Картинки, скрипты и стили грузятся ровно так же, как раньше.
Композит не включается на странице. Скорее всего, один из компонентов
голосует против. По умолчанию так делают, например, bitrix:lists,
bitrix:sale.personal.subscribe и bitrix:search.page. Достаточно одного
неадаптированного шаблона.
Статический кеш переписывается постоянно. Причины по частоте: случайные идентификаторы в разметке, зависимость от браузера, подстановка адреса запроса в атрибуты, данные сессии, разный контент для авторизованных и анонимных, условное подключение стилей и скриптов.
Динамическая зона «моргает». Сначала показывается заглушка из кеша, потом приходят настоящие данные - счётчик корзины прыгает с нуля на правильное значение. Лечится встроенным скриптом сразу после элемента или хранением значения в локальном хранилище браузера.
Скрытое поле с идентификатором сессии пустое. В кешируемом шаблоне так и должно быть - реальное значение подставит JavaScript. Это не ошибка.
Ответ 304 приходит только с третьего запроса. Тоже нормально: первый запрос создаёт кеш, второй отдаёт заголовок с датой изменения, и только третий может получить 304.
Папку статических страниц чистят вручную. Удалять её и править конфигурацию руками не нужно - есть штатный сброс кеша в настройках и cron-скрипт. Если всё же удалили вручную, придётся почистить служебный файл-флаг.
Частые вопросы
Что именно ускоряет композитный сайт?
Только время ответа сервера: готовый HTML отдаётся с диска или из memcached, без выполнения PHP и запросов к базе. Загрузка изображений, стилей и скриптов, установка соединения и работа DNS остаются прежними. Если узкое место в них, композит даст мало - смотрите в сторону оптимизации фронтенда и CDN.
Что выносить в динамическую зону?
Всё персональное и часто меняющееся: блок авторизации, счётчик корзины, просмотренные товары, баннеры с ротацией, относительное время и таймеры. Остальная страница должна быть одинаковой для всех - именно она попадает в статический кеш. Вкладывать зоны друг в друга нельзя, а компоненты внутри зоны автоматически считаются совместимыми с композитом.
Почему кеш перезаписывается на каждом запросе?
Значит, контрольная сумма страницы каждый раз новая. Ищите то, что различается между запросами: случайные идентификаторы вместо стабильного randString(), идентификатор сессии или пользователя прямо в шаблоне, время, адрес запроса в атрибутах, проверку cookie в PHP, условное подключение стилей и скриптов. Серверные значения на клиенте берут через BX.message().
Можно ли включить композит, если один компонент несовместим?
На той же странице - нет: голос против отключает композит целиком. Варианты два: адаптировать шаблон компонента, вынеся персональную часть в динамическую зону, либо оставить страницу без композита, если несовместимый компонент там принципиален. Заодно стоит исключить из композита группу администраторов - админ-панель кешировать не нужно.
Связанные темы
- Шаблоны сайта - где живут шаблоны компонентов
- Компоненты 2.0 - кеширование результата компонента
- Композит: эксплуатация - настройка, сброс кеша, диагностика
- Раздел Компоненты и шаблоны