Композитный сайт
Композитный сайт — очень полезная технология, если её использовать с умом. И как в любой новинке, в композите хватает недоработок и проблем.
В этом разделе собраны основные проблемы композита, причины и пути их решения.
Композит не сработает в следующих случаях
- Не включена настройка в админке, либо страница попадает под условия исключения, либо не входит в условия включения, либо страница не прошла проверку по параметрам (например компонент проголосовал против).
- В технологии работают только GET запросы. С другими запросами технология не работает.
- Адрес страницы начинается с
/bitrix
. - Есть служебная cookie _NCC (No Composite Cache), которая позволяет определять входит ли пользователь в группу, для которой разрешено отображение страниц по технологии или не входит.
- В
$_GET
есть параметрncc=1
. Если нужны собственные исключающие параметры по которым не будет работать композит, то используйте~EXCLUDE_PARAMS
в/home/bitrix/www/bitrix/html_pages/.config.php
. - Если в запросе есть сохранённая авторизация, то будет выдана страница по обычной технологии. Если авторизация сохранена, а пользователь принадлежит к группе, которая должна видеть страницу из композитного кеша, то он увидит её при повторном хите.
- В
REQUEST_URI
есть..
,.php
,.html
в середине адреса. (Это требование по безопасности.) - Если ajax-запрос сделан с помощью
BX.ajax
.
Основные проблемы композита
Тут собраны самые частые и типовые проблемы и ошибки.
Моргание контента
При динамической загрузке больших блоков (баннер, список элементов каталога) возникает неприятный для глаза эффект, моргания или прыгания контента страницы, особенно если этот контент находится на первом экране. Для устранения этого эффекта можно использовать метод $frame->setAnimation(true)
, он "включает" анимацию появления контента, подгружаемого через ajax. Просто и не раздражает глаз.
<div id="my_div">
<?
$frame = $this->createFrame('my_div', false)->begin();
// Включаем плавную анимацию
$frame->setAnimation(true);
?>
Динамический контент.
<?
$frame->end();
?>
</div>
JS и Композитный сайт
Очень важно понимать, что при композитном хите контент динамических областей физически не существует на странице, поэтому любые js-обработчики, завязанные на DOM-дерево внутри динамической области не сработают или сработают не так, как ожидается. К таким обработчикам можно отнести различные карусельки, стилизацию селектов и т.п.
При этом писать js в шаблон компонента — не самая лучшая идея и этого необходимо избегать всеми возможными способами (без фанатизма конечно же).
Решение проблемы очень простое — достаточно "дождаться", когда ajax-контент динамических областей подгрузится.
if (window.frameCacheVars !== undefined) {
BX.addCustomEvent("onFrameDataReceived", runFunction);
} else {
$(runFunction);
}
function runFunction() {
// Код, написанный тут, выполнится корректно и при обычном и при композитном хитах.
console.log('go-go-go');
}
Не стоит навешивать обработчики пользовательских событий (click, focus, hover, input и т.п.) внутри функции runFunction
из примера выше т.к. это пустая трата времени и некорректное написание js т.к. пользователь всёравно не сможет кликнуть по несуществующей кнопке :smile:.
Для пользовательских событий используйте нормальный код, который можно записать в самое начало js-файла:
$(document).on('click', '.selector', function(event) {
/* Обрабатываем клик по элементу .selector */
});
Такой код не зависит от композитного режима сайта и обработчик сработает тогда, когда это необходимо.
Иногда требуется выполнить какой-то js код в зависимости от того, загрузился лии нет динамический контент. Например кастомизация селектов. Для этого достаточно "слушать" события, которые сопровождают работу динамических областей.
// событие происходит перед началом цикла вставки дин. блоков.
BX.addCustomEvent('onFrameDataReceivedBefore', json);
// событие происходит перед вставкой каждого блока. Если для конкретного блока в шаблоне компонента было указано $frame->setAutoUpdate(false), то вставка динамического блока не происходит.
BX.addCustomEvent('onBeforeDynamicBlockUpdate', block, fromCache);
// событие происходит после цикла вставки динамических блоков.
BX.addCustomEvent('onFrameDataReceived', json);
Где:
- json — это все данные, которые пришли в композитном ajax-хите.
- block — это данные по конкретному инфоблоку (id, контент и другие).
- fromCache — равен true, когда данные вставляют из локальной SQL-базы.
Необычные или редкие проблемы композита
Тут собраны редкие или необычные и нелогичные проблемы композита
Куки + композит
Когда возникает:
- При установке шаблона сайта на основании значения куки пользователя.
Причины возникновения:
- При выполнении страницы композит учитывает только URL и служебные куки _NCC, остальные куки ему до лампочки.
Пути решения:
- "Отключить" композит для страниц, отображение которых зависит от cookies посетителя.
- Если возможно - посылать посетителя по другому адресу (например побильная версия сайта), при этом делать это лучше средствами nginx или apache.
Контент сайта попадает внутрь заголовка H1
Когда возникает:
- Фильтр каталога вынесен в другое место страницы через ShowViewContent.
- Попытка завернуть баннеры в динамическую область.
Причины возникновения:
- Некорректный расчёт динамических областей из-за отсутствия конкретных ID этих областей.
- Динамическая область вложена в другую динамическую область.
Пути решения:
- Указывать конкретные ID динамических областей
echo '<div id="my_div">';
$frame = $this->createFrame('my_div', false)->begin();
//динамический контент
$frame->beginStub();
//заглушка
$frame->end();
echo '</div>';
- Не включать одну динамическую область в другую.
Для подготовки раздела использовалась документация из курса, статья Композитный сайт: tips & tricks и собственные решения проблем, с которыми приходится сталкиваться в процессе работы.