Магазин открывается за три секунды, в час пик — за семь, а под нагрузкой распродажи и вовсе падает по таймауту. Разработчик смотрит в отладчик и видит сотни запросов к базе на одну страницу каталога: каждый клик пересобирает меню, список товаров, фильтр и подвал с нуля. Всё это в 1С-Битрикс решает не «оптимизация запросов вручную», а грамотно выстроенное кэширование — от кэша компонентов до тегового кэша и композита. Именно оно превращает тяжёлый каталог в витрину, которая отдаётся мгновенно.
Ниже — системный разбор кэширования в Битриксе: какие уровни кэша есть, чем управляемый кэш отличается от обычного, как работает теговая инвалидация по инфоблокам, как кэшировать в коде через D7 и $this->startResultCache, где хранить кэш (файлы, memcached, Redis) и как не сломать корзину и персональные цены. Это выжимка из наших проектов по ускорению интернет-магазинов на 1С-Битрикс — без теории ради теории.
Коротко
- В Битриксе несколько уровней кэша: кэш компонентов, управляемый (теговый) кэш, HTML-кэш/композит — они складываются, а не заменяют друг друга.
- Режим «Авто» = обычный кэш + теги: данные всегда свежие, а лишней пересборки нет. Это дефолт для каталога.
- Кэш в коде делают через D7 (
\Bitrix\Main\Data\Cache,TaggedCache) или$this->startResultCacheв компоненте. - Тяжёлый кэш выносят в память — memcached или Redis вместо файлов на диске.
- Персональное (корзина, авторизация, цены) не кэшируют; после обмена с 1С кэш инвалидируют по тегам и прогревают.
Зачем магазину на Битриксе продуманное кэширование
Любая страница в 1С-Битрикс без кэша собирается «с нуля»: стартует ядро, отрабатывает пролог, каждый компонент лезет в базу за своими данными, склеивается шаблон, отрабатывает эпилог. На простой странице это десятки запросов, на разделе каталога с фильтром, меню, хлебными крошками, блоками «хиты» и «новинки» — легко сотни. Пока посетителей мало, сервер справляется. Но трафик растёт нелинейно к нагрузке: в час пик тяжёлые запросы выстраиваются в очередь, база захлёбывается, и сайт «встаёт».
Кэширование разрывает эту зависимость. Один раз собранный результат сохраняется, и следующие посетители получают его почти бесплатно — без похода в базу и без пересборки. Грамотный кэш даёт три эффекта сразу:
- Скорость. Время генерации страницы падает с сотен миллисекунд до десятков, снижается время до первого байта (TTFB).
- Устойчивость под нагрузкой. Всплеск трафика не превращается в шторм запросов к базе — большинство посетителей обслуживается из кэша.
- Экономия ресурсов. Тот же хостинг держит в разы больше посетителей, потому что процессор и база не заняты повторной работой.
Обратная сторона — актуальность. Кэш по определению показывает «снимок» данных на момент сборки. Если цена изменилась, а кэш не сброшен, покупатель увидит старую цифру. Всё искусство кэширования в Битриксе сводится к балансу «быстро, но свежо»: кэшировать как можно больше, но сбрасывать ровно то, что изменилось, и ровно тогда, когда изменилось. Именно эту задачу решает теговый (управляемый) кэш, к которому мы придём чуть ниже.
Когда кэш решает, а когда маскирует проблему
Важно с самого начала честно разделить две ситуации. Кэш блестяще лечит «повторную сборку одного и того же»: если сто посетителей запрашивают один раздел каталога, нет смысла сто раз считать один список. Но кэш не лечит «медленную сборку самого первого раза»: если один тяжёлый запрос идёт пять секунд, кэш просто спрячет эту пятисекундную задержку от второго и последующих посетителей, а первый (и каждый после сброса кэша) всё равно её словит. Поэтому кэширование идёт в связке с оптимизацией запросов и правильной архитектурой каталога, а не вместо них.
Уровни кэша в 1С-Битрикс: общая карта
Первое, что стоит уложить в голове, — кэш в Битриксе не один. Это несколько слоёв, каждый со своей зоной ответственности. Они складываются: HTML-кэш стоит поверх кэша компонентов, а тот — поверх кэша данных. Понимание этой иерархии сразу подсказывает, где искать проблему, когда «что-то не кэшируется» или «показывает старое».
- Кэш данных. Самый низкий уровень: результат выборки из базы (список товаров, свойства, цены) сохраняется как сериализованный массив. Это то, что компонент кладёт в кэш «под капотом».
- Кэш компонентов. Результат работы компонента целиком — и данные, и отрисованный шаблон. Меню, список товаров, карточка берутся из кэша, а не считаются заново.
- Управляемый (теговый) кэш. Надстройка над кэшем компонентов: помечает кэши тегами и сбрасывает их по событию изменения данных, а не по таймеру.
- HTML-кэш и композит. Самый верхний уровень: кэшируется вся собранная HTML-страница целиком, статика отдаётся до запуска тяжёлого ядра, персональная динамика догружается отдельно.
Отдельно стоит хранилище кэша — оно ортогонально уровням. Любой из перечисленных кэшей физически лежит либо в файлах на диске, либо в оперативной памяти (memcached, Redis). Смена хранилища не меняет логику кэширования, но сильно влияет на скорость доступа к кэшу, особенно когда кэш-файлов десятки тысяч.
Кэш компонентов — основа скорости
Практический фундамент производительности магазина — включённый кэш у компонентов. Почти каждый штатный компонент (список и детальная каталога, меню, новости, хлебные крошки) имеет параметр «Тип кэширования» и «Время кэширования». Когда кэш включён, компонент при первом обращении собирает результат, сохраняет его и при последующих запросах с теми же параметрами отдаёт из кэша, не трогая базу.
Ключевой момент — ключ кэша. Компонент кэширует не «страницу вообще», а результат для конкретного набора входных параметров: раздел, номер страницы пагинации, сортировка, значения фильтра, группа пользователя (если это влияет на вывод). Каждой уникальной комбинации соответствует свой кэш-файл. Отсюда практическое следствие: чем больше вариаций (много сортировок, много комбинаций фильтра), тем больше кэш-файлов и тем важнее быстрое хранилище.
| Тип кэширования компонента | Что делает | Когда уместно |
|---|---|---|
| Авто (Managed) | Кэш + сброс по тегам при изменении данных | Дефолт для каталога, меню, витрины |
| Кэширован | Обычный кэш по времени жизни (TTL) | Данные, которые меняются по расписанию |
| Авто + доп. кэш AJAX | Кэш с учётом дополнительных запросов | Компоненты с подгрузкой |
| Не кэшировать | Каждый запрос считается заново | Только персональные блоки и отладка |
Автокэширование и режим «Авто»
«Авто» (автокэширование) — самый важный для магазина режим, и его стоит понять точно. Обычный кэш по времени жизни имеет неприятную дилемму: поставишь маленький TTL — данные свежие, но кэш почти не работает; поставишь большой — сайт быстрый, но посетитель видит устаревшее. Автокэширование снимает эту дилемму: кэш живёт «условно вечно», но сбрасывается по событию изменения данных, а не по таймеру.
Механика такая: пока компонент собирает результат в режиме «Авто», ядро запоминает, к каким инфоблокам он обращался, и помечает получившийся кэш соответствующими тегами. Как только в этих инфоблоках что-то меняется (правка товара, изменение цены, добавление позиции), платформа сбрасывает все кэши с этим тегом. Данные, которые не менялись, продолжают отдаваться из кэша сколько угодно долго.
Для витрины это идеальный компромисс: покупатель практически всегда видит актуальные данные, потому что кэш сбрасывается ровно в момент изменения, и при этом сайт не пересобирает то, что стабильно. Единственное условие — в настройках главного модуля должен быть включён управляемый кэш (managed_cache), иначе «Авто» деградирует до обычного кэша по TTL.
main). Без них режим компонента «Авто» не сможет опираться на теги и будет работать как обычный кэш. Это первое, что стоит проверить, если «Авто вроде включён, а старое всё равно висит».
Управляемый кэш (managed_cache) и теги
Управляемый кэш — сердце «умного» кэширования в Битриксе. Технически это подсистема, которая ведёт таблицу соответствий «тег → кэши» и умеет по одному тегу сбросить сразу все связанные кэши. Тегом может быть что угодно, но на практике самые полезные теги — автоматические теги инфоблоков вида iblock_id_ID, где ID — идентификатор инфоблока.
Когда компонент каталога в режиме «Авто» выбирает товары из инфоблока 12, его кэш помечается тегом iblock_id_12. Любое штатное изменение товара в этом инфоблоке дёргает событие, которое вызывает сброс по тегу iblock_id_12 — и все кэши, зависящие от этого инфоблока (список раздела, детальная, «хиты», меню каталога), инвалидируются разом. Разработчику не нужно вручную вычислять, какие страницы затронуты: за него это делает теговая модель.
Работать с тегами можно и вручную. Глобальный объект $CACHE_MANAGER и D7-класс TaggedCache позволяют регистрировать свои теги и сбрасывать кэш по ним — это нужно, когда данные приходят из нестандартного источника (внешнее API, свой highload-модуль, кастомная таблица) и стандартные события не срабатывают. К этому мы вернёмся в разделах про D7 и $CACHE_MANAGER.
| Понятие | Что это | Пример |
|---|---|---|
| Тег кэша | Метка, связывающая кэш с данными | iblock_id_12 |
| Регистрация тега | Пометка кэша тегом при сборке | registerTag('iblock_id_12') |
| Сброс по тегу | Инвалидация всех кэшей с тегом | clearByTag('iblock_id_12') |
| Автотег инфоблока | Тег, который ядро ставит само в режиме «Авто» | при выборке из инфоблока |
Теговый кэш: инвалидация по тегам инфоблоков
Разберём жизненный цикл тегового кэша подробнее, потому что именно здесь ломается большинство сценариев «показывает старое». Цикл состоит из четырёх фаз.
- Сборка и регистрация тега. Компонент в режиме «Авто» собирает данные из инфоблока и в процессе регистрирует тег
iblock_id_ID. Кэш сохраняется, а в таблице управляемого кэша появляется связь «этот тег → этот кэш». - Отдача из кэша. Пока данные не менялись, все последующие запросы получают готовый результат из кэша. Тег при этом просто «висит» и ждёт события.
- Событие изменения. Товар в инфоблоке правят через интерфейс или штатный API. Событие ядра
OnAfterIBlockElementUpdate(и родственные) инициирует сброс по тегуiblock_id_ID. - Инвалидация и пересборка. Все кэши с этим тегом помечаются недействительными. Следующий посетитель, попавший на такую страницу, соберёт её заново и создаст свежий кэш с новым тегом.
Отсюда видно, где рвётся цепочка. Если данные меняются в обход событий ядра — прямым SQL, нестандартным импортом, пакетной загрузкой без вызова событий — фаза 3 не срабатывает, тег не сбрасывается, и посетитель продолжает видеть старый кэш до истечения общего TTL (а он большой). Именно поэтому массовые операции и обмен с 1С требуют отдельной ручной инвалидации — об этом ниже.
HTML-кэш, автокомпозит и композитный сайт
Кэш компонентов ускоряет сборку блоков, но страница всё равно собирается на каждый запрос: стартует ядро, отрабатывают пролог и эпилог, склеиваются кэши компонентов в единый HTML. Следующий уровень — кэшировать саму собранную страницу целиком. Этим занимается композит (в интерфейсе — «Композитный сайт», технически связан с HTML-кэшем и автокомпозитом).
Идея композита: большая часть страницы у всех посетителей одинакова (шапка, меню, тело раздела, карточка, подвал). Эту статику сохраняют как готовый HTML и отдают мгновенно, ещё до запуска тяжёлой части ядра. Персональное (корзина, авторизация, цены) помечают как динамику и догружают отдельным быстрым запросом поверх статики. Для посетителя это выглядит как «страница открылась сразу, а корзина появилась через долю секунды».
Композит не отменяет кэш компонентов, а надстраивается над ним: динамическая часть по-прежнему пользуется кэшем компонентов. Поэтому правильный порядок внедрения — сначала навести порядок с кэшем компонентов и тегами, и только потом включать композит как финальный ускоритель. Подробный разбор того, что выносить в динамику и как не сломать корзину, — в отдельном материале про композитный сайт в 1С-Битрикс.
| Критерий | Кэш компонентов | HTML-кэш / композит |
|---|---|---|
| Что кэшируется | Отдельные блоки | Вся статическая страница |
| Запуск ядра на запрос | Да, каждый раз | Нет, статика до ядра |
| Скорость отдачи | Сотни мс | Десятки мс |
| Персональные блоки | В общем потоке | Выносятся в динамику |
D7: класс \Bitrix\Main\Data\Cache
Когда вы пишете собственный код (свой модуль, свой компонент, обработчик, страницу с нестандартной логикой), кэшировать выборки нужно руками. В современном ядре D7 за это отвечает класс \Bitrix\Main\Data\Cache. Базовый паттерн — «обёртка вокруг тяжёлого кода»: если валидный кэш есть, берём из него; если нет, выполняем тяжёлую логику и сохраняем результат.
use Bitrix\Main\Data\Cache;
$cache = Cache::createInstance();
$cacheTime = 3600; // время жизни, сек
$cacheId = 'my_top_products_' . $sectionId;
$cacheDir = '/my/top_products';
if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
// Кэш валиден — забираем готовые данные
$result = $cache->getVars();
} elseif ($cache->startDataCache()) {
// Кэша нет — выполняем тяжёлую выборку
$result = my_heavy_query($sectionId);
// (опционально) регистрируем теги — см. следующий раздел
$cache->endDataCache(['result' => $result]);
}
$data = $result['result'] ?? $result;
Разберём по шагам. initCache() проверяет, есть ли валидный кэш с таким ключом и не истёк ли он; если да — возвращает true, и данные берутся через getVars(). Если валидного кэша нет, startDataCache() открывает «запись» кэша, вы выполняете тяжёлую логику, а endDataCache() сохраняет переданный массив в кэш. Ключ кэша ($cacheId) обязан включать все параметры, влияющие на результат: раздел, фильтр, группу пользователя. Иначе разные запросы получат один и тот же кэш — классическая причина «показывает не то».
$cacheId. Забыли добавить в ключ группу пользователя — и оптовик увидит розничный кэш. Забыли добавить сортировку — и «по цене» покажет кэш «по популярности». Ключ кэша — это подпись входных данных.
D7: TaggedCache и регистрация тегов
Кэш из предыдущего раздела живёт по времени жизни. Чтобы он сбрасывался по событию изменения данных (как штатные компоненты в режиме «Авто»), к нему нужно привязать теги. В D7 за это отвечает TaggedCache, который получают через Application::getInstance()->getTaggedCache(). Теги регистрируют внутри блока сборки кэша.
use Bitrix\Main\Data\Cache;
use Bitrix\Main\Application;
$cache = Cache::createInstance();
$taggedCache = Application::getInstance()->getTaggedCache();
if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
$result = $cache->getVars();
} elseif ($cache->startDataCache()) {
// Открываем область тегированного кэша
$taggedCache->startTagCache($cacheDir);
$result = my_heavy_query($sectionId);
// Привязываем кэш к инфоблоку: сброс произойдёт при изменении его элементов
$taggedCache->registerTag('iblock_id_' . IBLOCK_ID);
$taggedCache->endTagCache();
$cache->endDataCache(['result' => $result]);
}
Теперь ваш собственный кэш ведёт себя как штатный: пока инфоблок не менялся, он отдаётся сколь угодно долго, а при первой же правке элемента сбрасывается по тегу iblock_id_ID. Тегов можно зарегистрировать несколько — например, если ваш блок выводит данные из двух инфоблоков или из инфоблока плюс highload-справочника. Это ровно та механика, что и у управляемого кэша компонентов, только под вашим контролем.
Когда данные приходят не из инфоблока, а из своей таблицы или внешнего источника, используют собственные теги — произвольные строки, которые вы регистрируете при сборке и сбрасываете вручную при обновлении источника. Главное — не смешивать пространства имён тегов и держать их осмысленными, чтобы позже было понятно, что и когда сбрасывать.
Кастомное кэширование: $this->startResultCache
Внутри компонента (в component.php или в class.php) есть более высокоуровневая обёртка — метод $this->startResultCache(). Он кэширует весь $arResult компонента и автоматически учитывает многие параметры в ключе кэша. Это стандартный способ кэшировать логику в кастомных компонентах.
// внутри component.php кастомного компонента
if ($this->startResultCache()) {
// Тяжёлая логика: выборки, обработка, формирование $arResult
$arResult['ITEMS'] = $this->getItems();
// Привязка к инфоблоку для автосброса по тегу
if (\Bitrix\Main\Loader::includeModule('iblock')) {
$this->__component->setResultCacheKeys([]); // при необходимости
}
global $CACHE_MANAGER;
$CACHE_MANAGER->RegisterTag('iblock_id_' . $arParams['IBLOCK_ID']);
$this->includeComponentTemplate();
} else {
// Кэш валиден — шаблон уже подключён, $arResult восстановлен
}
Логика зеркальна D7-паттерну: startResultCache() возвращает true, если валидного кэша нет и нужно собрать данные; внутри вы формируете $arResult, регистрируете теги и подключаете шаблон через includeComponentTemplate(). Если кэш валиден, метод возвращает false, а $arResult и вывод шаблона восстанавливаются из кэша автоматически.
Важная тонкость — дополнительные ключи кэша. По умолчанию startResultCache() учитывает шаблон, язык сайта, группы пользователя (если задано) и параметры компонента. Но если ваш результат зависит от чего-то ещё — GET-параметра, региона, значения из сессии, — это нужно явно передать в ключ, иначе разные состояния склеятся в один кэш. Передают дополнительный ключ первым аргументом метода или через SetTemplateCachedData / доп. кэш-ключи компонента.
$CACHE_MANAGER: ручное управление тегами
Глобальный объект $CACHE_MANAGER — «пульт» управляемого кэша в старом ядре, доступный из любого места. Он умеет три главные вещи: регистрировать теги, сбрасывать кэш по тегу и очищать кэш по каталогу. Это рабочая лошадка для нестандартных сценариев инвалидации.
global $CACHE_MANAGER;
// Регистрация тега при сборке (внутри области кэша)
$CACHE_MANAGER->RegisterTag('iblock_id_12');
// Ручной сброс всех кэшей, помеченных тегом
$CACHE_MANAGER->ClearByTag('iblock_id_12');
// Полная очистка каталога кэша (осторожно — точечно, не весь сайт)
$CACHE_MANAGER->CleanDir('/my/top_products');
Самый частый практический случай — сброс по тегу из обработчика события. Например, ваш модуль импорта заливает акции пакетно в обход стандартных событий инфоблока. Тогда после импорта вы сами вызываете $CACHE_MANAGER->ClearByTag('iblock_id_' . AKCII_IBLOCK) — и все кэши, зависящие от акций, инвалидируются. Так вы «докладываете» управляемому кэшу о том, о чём он не узнал сам.
Тот же объект помогает и в аварийных ситуациях: если кэш «залип» и показывает старое, точечный ClearByTag или CleanDir по нужному разделу решает проблему без полного сброса всего кэша сайта. Полный сброс (кнопка «Очистить весь кэш» в админке) — крайняя мера: после него весь сайт разом становится «холодным», и в час пик это само по себе создаёт нагрузку.
Где хранить кэш: файлы, memcached, Redis
Логика кэширования одна, а вот физическое хранилище можно менять — и это часто даёт самый заметный прирост на нагруженном магазине. По умолчанию Битрикс хранит кэш в файлах на диске. Пока кэш-файлов немного, это работает отлично. Но на большом каталоге с множеством комбинаций фильтра и сортировок кэш-файлов становятся десятки и сотни тысяч, и файловая система превращается в узкое место: медленное чтение мелких файлов, тяжёлая инвалидация, износ диска.
Решение — вынести кэш в оперативную память через внешнее хранилище. Настраивается это в файлах конфигурации (.settings.php для D7-кэша и параметрах кэша) без переписывания кода: вы меняете «драйвер» хранилища, а логика Cache, тегов и компонентов остаётся прежней.
| Хранилище | Плюсы | Минусы / когда |
|---|---|---|
| Файлы (по умолчанию) | Ничего не нужно ставить, работает везде | Тормозит на десятках тысяч кэш-файлов, нагружает диск |
| memcached | Кэш в памяти, быстрый доступ, простой «ключ-значение» | Данные не переживают перезапуск, нет сохранения на диск |
| Redis | Кэш в памяти, богаче по возможностям, умеет персистентность | Чуть сложнее в настройке; общий ресурс с сессиями/очередями |
Практический ориентир такой. Небольшому и среднему сайту с файловым кэшем на быстром SSD часто хватает и без внешнего хранилища. Как только каталог большой, кэш-файлов очень много, а под нагрузкой диск становится узким местом — переезд на memcached или Redis даёт ощутимый прирост. Между memcached и Redis для чистого кэша разница по скорости невелика: memcached проще, Redis универсальнее (то же хранилище удобно использовать под сессии). Выбор чаще диктуется тем, что уже развёрнуто на инфраструктуре.
Кэш меню
Меню в Битриксе — отдельная подсистема со своим кэшем, и о нём стоит сказать особо, потому что «залипшее меню» — классическая жалоба. Компонент bitrix:menu кэширует построенное дерево пунктов. Пока структура разделов и файлы .menu.php не менялись, меню отдаётся из кэша. Проблема возникает, когда пункты меню зависят от динамики: например, разделы каталога подтягиваются из инфоблока, или пункт показывается только определённой группе пользователей.
Если меню строится по инфоблоку каталога, его кэш нужно привязать к тегу этого инфоблока — тогда добавление нового раздела автоматически обновит меню. Если же меню зависит от прав пользователя, важно включить в ключ кэша группу пользователя, иначе гость и админ увидят одно и то же меню. Штатный компонент меню умеет учитывать это, но в кастомных сборках меню про группу нередко забывают.
Кэш инфоблоков и highload-блоков
Инфоблоки — главный источник данных магазина, и у них есть собственный слой кэширования результатов выборок. Когда включён кэш инфоблоков, повторные запросы элементов и свойств отдаются из кэша, а не из базы. В связке с управляемым кэшем это даёт теговую инвалидацию: правка элемента сбрасывает связанные кэши по тегу инфоблока.
Отдельно стоит упомянуть кэш свойств и «умную» работу с большими каталогами. Тяжёлые множественные свойства и привязки лучше кэшировать вместе с элементами, а не догружать отдельными запросами в цикле — иначе получается классический «эффект N+1», когда на список из ста товаров идёт сто дополнительных запросов за свойствами. Кэш инфоблока снимает эту боль только если выборка построена правильно (свойства запрошены разом), поэтому кэш и оптимизация запросов идут рука об руку.
Highload-блоки (большие справочники характеристик — бренды, единый список цветов, справочники совместимости) кэшируются через тот же D7-механизм Cache/TaggedCache. Их данные меняются реже товаров, поэтому справочники — идеальный кандидат на долгий кэш с тегами: собрали один раз, отдаём из памяти, сбрасываем только при обновлении справочника. Как highload-блоки участвуют в каталоге и фильтрации, мы разбираем в материале про умный фильтр и фасетный индекс — там кэш компонента фильтра и фасет работают в одной связке. Если проект строится вокруг больших справочников и высоких нагрузок, имеет смысл сразу закладывать архитектуру под highload-проект на Битриксе, где кэш и хранилище проектируют с запасом.
Что НЕ кэшировать: корзина, авторизация, цены
Кэш ускоряет всё, что одинаково для всех. Но у магазина есть блоки, которые у каждого посетителя свои, и их кэшировать нельзя — иначе один покупатель увидит данные другого. Это самое опасное место кэширования, где ошибка стоит репутации.
| Блок | Кэшировать? | Почему |
|---|---|---|
| Каталог, карточка, описание товара | Да | Одинаковы для всех, меняются редко |
| Меню, подвал, контент раздела | Да | Общие для всех посетителей |
| Корзина в шапке (товары, сумма) | Нет | Персональна для каждого |
| Блок авторизации, имя пользователя | Нет | Зависит от того, кто вошёл |
| Персональные и оптовые цены | Нет / с ключом по группе | Различаются по группе клиента |
| Кнопка «купить / в корзине» | Нет | Зависит от состава корзины |
| Личный кабинет, история заказов | Нет | Полностью персональны |
Особая осторожность — с ценами в B2B. Если у вас разные цены для розницы и опта, цену нельзя кэшировать «для всех»: либо она выводится в некэшируемой (динамической) области, либо в ключ кэша обязательно входит группа пользователя, чтобы у каждой группы был свой кэш. Иначе авторизованный оптовик увидит закэшированную розничную цену — или наоборот. Как типы цен приходят из учётной системы и как их корректно показывать нужной группе, мы разбираем в материале про интеграцию магазина с 1С.
Технически персональные блоки решают тремя способами: (1) отключают кэш для блока целиком; (2) выносят в динамику композита; (3) подгружают отдельным AJAX-запросом поверх закэшированной статики. Последний вариант хорош тем, что тяжёлая часть страницы кэшируется полностью, а «оживление» персонального идёт быстрым лёгким запросом.
Кэширование и Core Web Vitals
Скорость — не только ощущение, но и измеримые метрики Core Web Vitals, которые учитывает поиск. Кэширование влияет на них через один ключевой параметр — время генерации страницы на сервере, которое напрямую формирует TTFB (время до первого байта). Чем быстрее сервер отдаёт первый байт, тем раньше браузер начинает рисовать страницу.
- LCP (Largest Contentful Paint) — время отрисовки крупнейшего элемента экрана. Кэш и композит отдают статику с основным контентом быстро, поэтому LCP улучшается заметнее всего.
- TTFB — фундамент под всеми метриками. Кэширование снижает его напрямую: страница из кэша отдаётся за десятки миллисекунд вместо сотен.
- CLS (Cumulative Layout Shift) — сдвиги вёрстки. Кэш сам по себе его не чинит, но при подгрузке персональной динамики важно резервировать место, чтобы блоки не «прыгали».
- INP (Interaction to Next Paint) — отзывчивость. Кэш разгружает сервер в пики, что косвенно помогает, но INP в основном зависит от фронтенда и скриптов.
Главное — не переоценивать кэш. Он лечит «медленный бэкенд и повторную сборку», но не чинит тяжёлый JavaScript, неоптимизированные картинки и сдвиги вёрстки. Это разные источники проблем, и Core Web Vitals улучшают комплексно. Как именно проседают LCP, CLS и INP в магазине на Битриксе и чем их лечить по отдельности — тема материала про Core Web Vitals для интернет-магазина. Кэширование там — обязательная база, на которой стоит всё остальное.
Прогрев кэша
У кэша есть «холодное» состояние — когда его ещё нет, и страница собирается тяжёлым способом. Первый посетитель после сброса кэша всегда попадает на такую холодную сборку и ловит именно ту задержку, ради устранения которой кэш и настраивали. На витрине с большим трафиком это заметно: сбросили кэш каталога — и десятки первых посетителей одновременно инициируют тяжёлые пересборки, создавая всплеск нагрузки (иногда это называют «эффектом стада»).
Прогрев решает проблему: кэш строят заранее, до прихода живых посетителей. По ключевым страницам проходят по расписанию или ботом-обходчиком сразу после сброса, чтобы к моменту прихода трафика кэш уже лежал готовым. Прогревать имеет смысл «горячую» верхушку — то, куда идёт основной трафик:
- Главная страница.
- Верхние разделы каталога и популярные категории.
- Карточки товаров-хитов и посадочные под рекламу.
Прогревать весь каталог из десятков тысяч страниц разом смысла нет — это само по себе тяжёлая операция. Разумнее прогреть верхушку, а остальным страницам дать собраться по первому обращению. Прогрев особенно важен после планового обмена с 1С и после массового сброса кэша: связка «сброс → прогрев в часы низкой нагрузки» держит витрину днём быстрой и «тёплой».
Инвалидация после обмена с 1С
Обмен с 1С — главный источник массовых изменений данных в магазине, и именно вокруг него ломается больше всего кэш-сценариев. Когда обмен идёт через штатный модуль и меняет товары стандартными средствами, теговый кэш инвалидируется по тегам инфоблоков автоматически — фаза «событие изменения» срабатывает штатно.
Сложности начинаются при больших пакетных обменах. Обмен заливает в базу тысячи позиций, и если он идёт в обход стандартных событий (прямые операции, отложенная индексация, нестандартный формат), теговый сброс может не сработать вовремя — на витрине останутся старые цены и остатки. Дисциплина здесь такая же, как с фасетным индексом умного фильтра: обмен → инвалидация → прогрев.
- Дождаться завершения обмена. Инвалидацию запускают после того, как пакет данных полностью залит, а не во время загрузки.
- Сбросить нужные теги. Через
$CACHE_MANAGER->ClearByTag()или D7 сбрасывают теги затронутых инфоблоков — точечно, а не весь кэш сайта. - Перестроить смежные индексы. Заодно обновляют фасетный индекс фильтра и поиск, если они завязаны на те же данные.
- Прогреть верхушку. По расписанию проходят по главной и верхним разделам, чтобы днём витрина работала на свежем и тёплом кэше.
Всю эту цепочку удобно повесить одной ночной процедурой на агент или планировщик после планового обмена. Тогда днём посетители всегда видят актуальные данные и не попадают на холодные пересборки. Подробно механику обмена и его влияние на витрину мы разбираем в материале про интеграцию магазина с 1С.
Битые сценарии сброса кэша
Отдельно соберём типичные «битые» сценарии инвалидации — ситуации, когда кэш ведёт себя не так, как ждёт разработчик. Они повторяются из проекта в проект.
- Данные меняются в обход событий. Прямой SQL, пакетный импорт без вызова событий инфоблока, изменение через нестандартный API — тег не сбрасывается, кэш висит старый. Лечится ручным
ClearByTagпосле операции. - Отключён управляемый кэш. В настройках модуля выключено «Управляемое кеширование», а компоненты стоят в «Авто». Теги не работают, кэш живёт по TTL, изменения не видны сразу. Лечится включением managed_cache.
- Неполный ключ кэша. В ключ не включили параметр, влияющий на результат (группа, регион, сортировка) — разные состояния склеились в один кэш. Лечится добавлением параметра в ключ.
- Кэш зарегистрирован без тега. Свой D7-кэш собран без
registerTag— он не сбрасывается по событию и живёт до истечения TTL. Лечится регистрацией тегов. - Сброс «всего кэша» вместо точечного. Привычка чистить весь кэш сайта на каждое изменение обнуляет весь прогрев и роняет производительность в пик. Лечится точечной инвалидацией по тегу или каталогу.
- Кэш и права доступа. Закэшировали блок, зависящий от прав, без учёта группы — пользователь видит чужой вариант. Лечится ключом по группе или отключением кэша для такого блока.
Общий диагностический приём — отладочная панель Битрикса и профилировщик: посмотрите число и время SQL-запросов на странице. Много тяжёлых запросов на каждый запрос страницы означает, что кэш либо выключен, либо не срабатывает. Мало запросов, но страница всё равно медленная — узкое место не в кэше, а в шаблоне, фронтенде или самой тяжёлой первой сборке.
Частые ошибки кэширования
Большинство проблем с кэшем в Битриксе повторяются. Зная их заранее, вы сэкономите дни отладки.
- Компонент стоит «Не кэшировать». Оставили после отладки — каждый клик по каталогу пересобирается с нуля. Проверяйте тип кэша перед релизом.
- Режим «Авто» без managed_cache. Теги не работают, «Авто» деградирует до TTL. Включите управляемый кэш в настройках модуля.
- Персональное в общем кэше. Корзина, цена или имя пользователя попали в кэш — посетители видят чужие данные. Самая опасная ошибка; выносите персональное из кэша.
- Неполный ключ кэша. Забыли включить группу или регион — разные состояния склеились. Ключ должен отражать все входные параметры.
- Свой кэш без тегов. D7-кэш собран без
registerTag— не сбрасывается по событию. Привязывайте кэш к инфоблокам тегами. - Файловый кэш на огромном каталоге. Десятки тысяч кэш-файлов душат диск. Выносите кэш в memcached или Redis.
- Нет прогрева после сброса. Первые посетители ловят холодную сборку и создают всплеск нагрузки. Прогревайте верхушку.
- Кэш не сбрасывается после обмена с 1С. Пакетный обмен в обход событий оставляет старые данные. Настройте ручную инвалидацию по тегам после обмена.
- Полный сброс кэша по любому поводу. Обнуляет прогрев и роняет пик. Сбрасывайте точечно — по тегу или каталогу.
Чек-лист по кэшированию
Короткий список, по которому удобно свериться перед релизом и после настройки кэша:
- В настройках главного модуля включены автокэширование и управляемый (теговый) кэш.
- У витринных компонентов (каталог, меню, витрина) тип кэша — «Авто», а не «Не кэшировать».
- Кастомный код кэширует тяжёлые выборки через D7
Cacheс полным ключом. - Собственные кэши привязаны к данным тегами (
registerTag/$CACHE_MANAGER). - Персональные блоки (корзина, авторизация, цены, кнопки покупки) исключены из общего кэша или вынесены в динамику.
- Для B2B цены кэшируются с ключом по группе клиента или отдаются динамически.
- На большом каталоге кэш вынесен в память (memcached или Redis), а не лежит только в файлах.
- Настроен прогрев ключевых страниц после сброса кэша.
- После обмена с 1С кэш инвалидируется по тегам, фасет перестраивается, верхушка прогревается.
- Инвалидация точечная (по тегу/каталогу), полный сброс — только как крайняя мера.
- Композит включён поверх грамотного кэша компонентов, а не вместо него.
Вывод
Кэширование в 1С-Битрикс — это не одна галочка, а слоёная система: кэш данных, кэш компонентов, управляемый теговый кэш и HTML-кэш с композитом. Они складываются, и каждый слой экономит всё более крупный «кусок» работы — от одной выборки до целой собранной страницы. Ключ к скорости без потери актуальности — теговый (управляемый) кэш: он держит данные свежими, сбрасываясь ровно по событию изменения, а не по таймеру.
Практический порядок такой: включить автокэширование и управляемый кэш, поставить витринным компонентам режим «Авто», кэшировать свой код через D7 с полным ключом и тегами, вынести персональное из кэша, при больших нагрузках переехать на memcached или Redis, наладить прогрев и точечную инвалидацию после обмена с 1С, и только поверх всего — включить композит. Сделайте эти вещи по порядку — и магазин будет открываться мгновенно даже на большом каталоге и в час пик. Если магазин уже нагружен и растёт, кэш и хранилище стоит проектировать с запасом — это часть архитектуры корпоративного сайта на Битриксе и любого серьёзного магазина, а не «оптимизация на потом». Другие материалы по производительности и архитектуре собраны в рубрике «Разработка и архитектура».