До 10%Рекомендуйте нас и получайте процент за каждого приведённого клиента

Кэширование в 1С-Битрикс: теговый кэш, автокэш, D7 и композит

Кэширование в 1С-Битрикс: уровни кэша, теговый и управляемый кэш, memcached и Redis, прогрев и инвалидация

Магазин открывается за три секунды, в час пик — за семь, а под нагрузкой распродажи и вовсе падает по таймауту. Разработчик смотрит в отладчик и видит сотни запросов к базе на одну страницу каталога: каждый клик пересобирает меню, список товаров, фильтр и подвал с нуля. Всё это в 1С-Битрикс решает не «оптимизация запросов вручную», а грамотно выстроенное кэширование — от кэша компонентов до тегового кэша и композита. Именно оно превращает тяжёлый каталог в витрину, которая отдаётся мгновенно.

Ниже — системный разбор кэширования в Битриксе: какие уровни кэша есть, чем управляемый кэш отличается от обычного, как работает теговая инвалидация по инфоблокам, как кэшировать в коде через D7 и $this->startResultCache, где хранить кэш (файлы, memcached, Redis) и как не сломать корзину и персональные цены. Это выжимка из наших проектов по ускорению интернет-магазинов на 1С-Битрикс — без теории ради теории.

Коротко

  • В Битриксе несколько уровней кэша: кэш компонентов, управляемый (теговый) кэш, HTML-кэш/композит — они складываются, а не заменяют друг друга.
  • Режим «Авто» = обычный кэш + теги: данные всегда свежие, а лишней пересборки нет. Это дефолт для каталога.
  • Кэш в коде делают через D7 (\Bitrix\Main\Data\Cache, TaggedCache) или $this->startResultCache в компоненте.
  • Тяжёлый кэш выносят в память — memcached или Redis вместо файлов на диске.
  • Персональное (корзина, авторизация, цены) не кэшируют; после обмена с 1С кэш инвалидируют по тегам и прогревают.

Зачем магазину на Битриксе продуманное кэширование

Любая страница в 1С-Битрикс без кэша собирается «с нуля»: стартует ядро, отрабатывает пролог, каждый компонент лезет в базу за своими данными, склеивается шаблон, отрабатывает эпилог. На простой странице это десятки запросов, на разделе каталога с фильтром, меню, хлебными крошками, блоками «хиты» и «новинки» — легко сотни. Пока посетителей мало, сервер справляется. Но трафик растёт нелинейно к нагрузке: в час пик тяжёлые запросы выстраиваются в очередь, база захлёбывается, и сайт «встаёт».

Кэширование разрывает эту зависимость. Один раз собранный результат сохраняется, и следующие посетители получают его почти бесплатно — без похода в базу и без пересборки. Грамотный кэш даёт три эффекта сразу:

Обратная сторона — актуальность. Кэш по определению показывает «снимок» данных на момент сборки. Если цена изменилась, а кэш не сброшен, покупатель увидит старую цифру. Всё искусство кэширования в Битриксе сводится к балансу «быстро, но свежо»: кэшировать как можно больше, но сбрасывать ровно то, что изменилось, и ровно тогда, когда изменилось. Именно эту задачу решает теговый (управляемый) кэш, к которому мы придём чуть ниже.

Когда кэш решает, а когда маскирует проблему

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

Уровни кэша в 1С-Битрикс: общая карта

Первое, что стоит уложить в голове, — кэш в Битриксе не один. Это несколько слоёв, каждый со своей зоной ответственности. Они складываются: HTML-кэш стоит поверх кэша компонентов, а тот — поверх кэша данных. Понимание этой иерархии сразу подсказывает, где искать проблему, когда «что-то не кэшируется» или «показывает старое».

Отдельно стоит хранилище кэша — оно ортогонально уровням. Любой из перечисленных кэшей физически лежит либо в файлах на диске, либо в оперативной памяти (memcached, Redis). Смена хранилища не меняет логику кэширования, но сильно влияет на скорость доступа к кэшу, особенно когда кэш-файлов десятки тысяч.

Стек кэширования в 1С-Битрикс HTML-кэш / композит вся страница целиком, статика мгновенно Управляемый (теговый) кэш сброс по тегам инфоблоков Кэш компонентов данные + отрисованный шаблон Кэш данных сериализованные выборки из базы выше — крупнее блок кэша
Схема: уровни кэша складываются снизу вверх — от кэша данных до HTML-кэша; чем выше слой, тем крупнее «кусок» страницы он экономит.

Кэш компонентов — основа скорости

Практический фундамент производительности магазина — включённый кэш у компонентов. Почти каждый штатный компонент (список и детальная каталога, меню, новости, хлебные крошки) имеет параметр «Тип кэширования» и «Время кэширования». Когда кэш включён, компонент при первом обращении собирает результат, сохраняет его и при последующих запросах с теми же параметрами отдаёт из кэша, не трогая базу.

Ключевой момент — ключ кэша. Компонент кэширует не «страницу вообще», а результат для конкретного набора входных параметров: раздел, номер страницы пагинации, сортировка, значения фильтра, группа пользователя (если это влияет на вывод). Каждой уникальной комбинации соответствует свой кэш-файл. Отсюда практическое следствие: чем больше вариаций (много сортировок, много комбинаций фильтра), тем больше кэш-файлов и тем важнее быстрое хранилище.

Тип кэширования компонентаЧто делаетКогда уместно
Авто (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')
Автотег инфоблокаТег, который ядро ставит само в режиме «Авто»при выборке из инфоблока

Теговый кэш: инвалидация по тегам инфоблоков

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

  1. Сборка и регистрация тега. Компонент в режиме «Авто» собирает данные из инфоблока и в процессе регистрирует тег iblock_id_ID. Кэш сохраняется, а в таблице управляемого кэша появляется связь «этот тег → этот кэш».
  2. Отдача из кэша. Пока данные не менялись, все последующие запросы получают готовый результат из кэша. Тег при этом просто «висит» и ждёт события.
  3. Событие изменения. Товар в инфоблоке правят через интерфейс или штатный API. Событие ядра OnAfterIBlockElementUpdate (и родственные) инициирует сброс по тегу iblock_id_ID.
  4. Инвалидация и пересборка. Все кэши с этим тегом помечаются недействительными. Следующий посетитель, попавший на такую страницу, соберёт её заново и создаст свежий кэш с новым тегом.

Отсюда видно, где рвётся цепочка. Если данные меняются в обход событий ядра — прямым SQL, нестандартным импортом, пакетной загрузкой без вызова событий — фаза 3 не срабатывает, тег не сбрасывается, и посетитель продолжает видеть старый кэш до истечения общего TTL (а он большой). Именно поэтому массовые операции и обмен с 1С требуют отдельной ручной инвалидации — об этом ниже.

Жизненный цикл тега iblock_id_12 1. Сборка registerTag(iblock_id_12) 2. Отдача из кэша без запросов к базе 3. Правка товара OnAfterIBlockElementUpdate 4. Сброс по тегу clearByTag → пересборка
Схема: кэш регистрирует тег при сборке и отдаётся до тех пор, пока правка товара не вызовет событие ядра и сброс по тегу с последующей пересборкой.

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 / доп. кэш-ключи компонента.

Не кэшируйте персональное в startResultCache. Если компонент выводит корзину, персональную цену или имя пользователя, его результат нельзя класть в общий кэш — либо отключите кэш для такого блока, либо вынесите персональную часть в отдельный некэшируемый вывод (или в динамику композита). Иначе первый посетитель «запечатает» свои данные для всех.

$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 универсальнее (то же хранилище удобно использовать под сессии). Выбор чаще диктуется тем, что уже развёрнуто на инфраструктуре.

Сессии — отдельная история. В памяти удобно хранить не только кэш, но и пользовательские сессии (модуль вынесения сессий в Redis/memcached). Это снимает с базы нагрузку от таблицы сессий на сайтах с большим онлайном. Но не путайте: кэш и сессии — разные подсистемы, и настраиваются они отдельно, хоть и могут жить в одном Redis.

Хранилище кэша: один код — разные бэкенды Bitrix\Main\Data\Cache единый API кэша Файлы на диске по умолчанию просто, но медленно на многих файлах memcached кэш в памяти ключ → значение без персистентности Redis кэш в памяти богаче, персистентность + сессии/очереди
Схема: единый API кэша Битрикса работает поверх любого хранилища — файлов, memcached или Redis; смена бэкенда не требует переписывать код.

Кэш меню

Меню в Битриксе — отдельная подсистема со своим кэшем, и о нём стоит сказать особо, потому что «залипшее меню» — классическая жалоба. Компонент bitrix:menu кэширует построенное дерево пунктов. Пока структура разделов и файлы .menu.php не менялись, меню отдаётся из кэша. Проблема возникает, когда пункты меню зависят от динамики: например, разделы каталога подтягиваются из инфоблока, или пункт показывается только определённой группе пользователей.

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

Симптом: добавили раздел в каталог, а в меню его нет. Почти всегда это незакэшированная связь меню с инфоблоком: кэш меню не помечен тегом каталога и держится до истечения TTL. Лечится привязкой тега или (разово) точечным сбросом кэша меню.

Кэш инфоблоков и highload-блоков

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

Отдельно стоит упомянуть кэш свойств и «умную» работу с большими каталогами. Тяжёлые множественные свойства и привязки лучше кэшировать вместе с элементами, а не догружать отдельными запросами в цикле — иначе получается классический «эффект N+1», когда на список из ста товаров идёт сто дополнительных запросов за свойствами. Кэш инфоблока снимает эту боль только если выборка построена правильно (свойства запрошены разом), поэтому кэш и оптимизация запросов идут рука об руку.

Highload-блоки (большие справочники характеристик — бренды, единый список цветов, справочники совместимости) кэшируются через тот же D7-механизм Cache/TaggedCache. Их данные меняются реже товаров, поэтому справочники — идеальный кандидат на долгий кэш с тегами: собрали один раз, отдаём из памяти, сбрасываем только при обновлении справочника. Как highload-блоки участвуют в каталоге и фильтрации, мы разбираем в материале про умный фильтр и фасетный индекс — там кэш компонента фильтра и фасет работают в одной связке. Если проект строится вокруг больших справочников и высоких нагрузок, имеет смысл сразу закладывать архитектуру под highload-проект на Битриксе, где кэш и хранилище проектируют с запасом.

Что НЕ кэшировать: корзина, авторизация, цены

Кэш ускоряет всё, что одинаково для всех. Но у магазина есть блоки, которые у каждого посетителя свои, и их кэшировать нельзя — иначе один покупатель увидит данные другого. Это самое опасное место кэширования, где ошибка стоит репутации.

БлокКэшировать?Почему
Каталог, карточка, описание товараДаОдинаковы для всех, меняются редко
Меню, подвал, контент разделаДаОбщие для всех посетителей
Корзина в шапке (товары, сумма)НетПерсональна для каждого
Блок авторизации, имя пользователяНетЗависит от того, кто вошёл
Персональные и оптовые ценыНет / с ключом по группеРазличаются по группе клиента
Кнопка «купить / в корзине»НетЗависит от состава корзины
Личный кабинет, история заказовНетПолностью персональны

Особая осторожность — с ценами в B2B. Если у вас разные цены для розницы и опта, цену нельзя кэшировать «для всех»: либо она выводится в некэшируемой (динамической) области, либо в ключ кэша обязательно входит группа пользователя, чтобы у каждой группы был свой кэш. Иначе авторизованный оптовик увидит закэшированную розничную цену — или наоборот. Как типы цен приходят из учётной системы и как их корректно показывать нужной группе, мы разбираем в материале про интеграцию магазина с 1С.

Технически персональные блоки решают тремя способами: (1) отключают кэш для блока целиком; (2) выносят в динамику композита; (3) подгружают отдельным AJAX-запросом поверх закэшированной статики. Последний вариант хорош тем, что тяжёлая часть страницы кэшируется полностью, а «оживление» персонального идёт быстрым лёгким запросом.

Поток запроса: cache hit vs cache miss Запрос Кэш есть? проверка ключа HIT Отдать из кэша без запросов к базе, десятки мс MISS База → сборка → запись в кэш тяжело, но один раз
Схема: при попадании (HIT) страница отдаётся из кэша мгновенно; при промахе (MISS) идёт тяжёлая сборка с записью в кэш — она случается один раз до следующего сброса.

Кэширование и Core Web Vitals

Скорость — не только ощущение, но и измеримые метрики Core Web Vitals, которые учитывает поиск. Кэширование влияет на них через один ключевой параметр — время генерации страницы на сервере, которое напрямую формирует TTFB (время до первого байта). Чем быстрее сервер отдаёт первый байт, тем раньше браузер начинает рисовать страницу.

Главное — не переоценивать кэш. Он лечит «медленный бэкенд и повторную сборку», но не чинит тяжёлый JavaScript, неоптимизированные картинки и сдвиги вёрстки. Это разные источники проблем, и Core Web Vitals улучшают комплексно. Как именно проседают LCP, CLS и INP в магазине на Битриксе и чем их лечить по отдельности — тема материала про Core Web Vitals для интернет-магазина. Кэширование там — обязательная база, на которой стоит всё остальное.

Прогрев кэша

У кэша есть «холодное» состояние — когда его ещё нет, и страница собирается тяжёлым способом. Первый посетитель после сброса кэша всегда попадает на такую холодную сборку и ловит именно ту задержку, ради устранения которой кэш и настраивали. На витрине с большим трафиком это заметно: сбросили кэш каталога — и десятки первых посетителей одновременно инициируют тяжёлые пересборки, создавая всплеск нагрузки (иногда это называют «эффектом стада»).

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

Прогревать весь каталог из десятков тысяч страниц разом смысла нет — это само по себе тяжёлая операция. Разумнее прогреть верхушку, а остальным страницам дать собраться по первому обращению. Прогрев особенно важен после планового обмена с 1С и после массового сброса кэша: связка «сброс → прогрев в часы низкой нагрузки» держит витрину днём быстрой и «тёплой».

Инвалидация после обмена с 1С

Обмен с 1С — главный источник массовых изменений данных в магазине, и именно вокруг него ломается больше всего кэш-сценариев. Когда обмен идёт через штатный модуль и меняет товары стандартными средствами, теговый кэш инвалидируется по тегам инфоблоков автоматически — фаза «событие изменения» срабатывает штатно.

Сложности начинаются при больших пакетных обменах. Обмен заливает в базу тысячи позиций, и если он идёт в обход стандартных событий (прямые операции, отложенная индексация, нестандартный формат), теговый сброс может не сработать вовремя — на витрине останутся старые цены и остатки. Дисциплина здесь такая же, как с фасетным индексом умного фильтра: обмен → инвалидация → прогрев.

  1. Дождаться завершения обмена. Инвалидацию запускают после того, как пакет данных полностью залит, а не во время загрузки.
  2. Сбросить нужные теги. Через $CACHE_MANAGER->ClearByTag() или D7 сбрасывают теги затронутых инфоблоков — точечно, а не весь кэш сайта.
  3. Перестроить смежные индексы. Заодно обновляют фасетный индекс фильтра и поиск, если они завязаны на те же данные.
  4. Прогреть верхушку. По расписанию проходят по главной и верхним разделам, чтобы днём витрина работала на свежем и тёплом кэше.

Всю эту цепочку удобно повесить одной ночной процедурой на агент или планировщик после планового обмена. Тогда днём посетители всегда видят актуальные данные и не попадают на холодные пересборки. Подробно механику обмена и его влияние на витрину мы разбираем в материале про интеграцию магазина с 1С.

Связка с обменом. Поставьте на планировщик сценарий: после ночного обмена — сброс тегов затронутых инфоблоков, перестроение фасета фильтра и прогрев главной и верхних категорий. Это устраняет и «старые цены на витрине», и «холодный сайт утром».

Битые сценарии сброса кэша

Отдельно соберём типичные «битые» сценарии инвалидации — ситуации, когда кэш ведёт себя не так, как ждёт разработчик. Они повторяются из проекта в проект.

Общий диагностический приём — отладочная панель Битрикса и профилировщик: посмотрите число и время SQL-запросов на странице. Много тяжёлых запросов на каждый запрос страницы означает, что кэш либо выключен, либо не срабатывает. Мало запросов, но страница всё равно медленная — узкое место не в кэше, а в шаблоне, фронтенде или самой тяжёлой первой сборке.

Частые ошибки кэширования

Большинство проблем с кэшем в Битриксе повторяются. Зная их заранее, вы сэкономите дни отладки.

Чек-лист по кэшированию

Короткий список, по которому удобно свериться перед релизом и после настройки кэша:

Вывод

Кэширование в 1С-Битрикс — это не одна галочка, а слоёная система: кэш данных, кэш компонентов, управляемый теговый кэш и HTML-кэш с композитом. Они складываются, и каждый слой экономит всё более крупный «кусок» работы — от одной выборки до целой собранной страницы. Ключ к скорости без потери актуальности — теговый (управляемый) кэш: он держит данные свежими, сбрасываясь ровно по событию изменения, а не по таймеру.

Практический порядок такой: включить автокэширование и управляемый кэш, поставить витринным компонентам режим «Авто», кэшировать свой код через D7 с полным ключом и тегами, вынести персональное из кэша, при больших нагрузках переехать на memcached или Redis, наладить прогрев и точечную инвалидацию после обмена с 1С, и только поверх всего — включить композит. Сделайте эти вещи по порядку — и магазин будет открываться мгновенно даже на большом каталоге и в час пик. Если магазин уже нагружен и растёт, кэш и хранилище стоит проектировать с запасом — это часть архитектуры корпоративного сайта на Битриксе и любого серьёзного магазина, а не «оптимизация на потом». Другие материалы по производительности и архитектуре собраны в рубрике «Разработка и архитектура».

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

Чем теговый (управляемый) кэш отличается от обычного кэша по времени жизни?

Обычный кэш живёт по времени жизни (TTL): он просто устаревает через заданное число секунд, независимо от того, менялись данные или нет. Теговый кэш (managed_cache) привязывает кэш к «тегам» — меткам данных, например к конкретному инфоблоку. Когда товар в этом инфоблоке меняется, платформа сбрасывает по тегу все связанные кэши сразу, а нетронутые данные продолжают отдаваться из кэша. В результате посетитель почти всегда видит актуальные данные и при этом сайт не пересобирает то, что не менялось. Именно поэтому в большинстве компонентов каталога рекомендуют режим кэша «Авто» с включённым управляемым кэшем.

Что означает тип кэша «Авто» в настройках компонента?

Режим «Авто» — это связка обычного кэша с управляемым (теговым) кэшем. Компонент кэширует результат, но вместо того чтобы ждать истечения TTL, помечает кэш тегами инфоблоков, к которым обращался. Как только данные в этих инфоблоках меняются, кэш автоматически сбрасывается по тегу. Для витрины магазина это оптимальный режим: данные всегда свежие, а лишней пересборки нет. Чтобы «Авто» работал, в настройках главного модуля должно быть включено «Управляемый кэш» (managed_cache).

Что нельзя кэшировать в интернет-магазине на Битриксе?

Нельзя кэшировать всё, что персонально или быстро меняется: содержимое корзины, блок авторизации и имя пользователя, персональные и оптовые цены, кнопки «купить / в корзине», историю заказов и личный кабинет, актуальный остаток при жёстком дефиците. Если такой блок попадёт в общий кэш, его закэшированное значение увидят все посетители — один покупатель может увидеть чужую корзину или чужую цену. Персональные блоки либо исключают из кэша, либо выносят в динамику композита, либо подгружают отдельным AJAX-запросом.

memcached или Redis — что выбрать под хранилище кэша Битрикса?

Оба переносят кэш из файлов в оперативную память и снимают нагрузку с диска, что особенно заметно на большом числе кэш-файлов. memcached проще, работает как быстрый распределённый словарь «ключ — значение» и исторически хорошо интегрирован с Битриксом. Redis богаче по возможностям, умеет сохранять данные на диск и лучше подходит, когда то же хранилище используют ещё и под сессии или очереди. Для типичного магазина оба варианта дают схожий выигрыш по скорости кэша; выбор чаще определяется тем, что уже развёрнуто и что умеет поддерживать ваш хостинг или админ.

Нужно ли сбрасывать кэш после обмена с 1С?

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

Что такое прогрев кэша и зачем он нужен?

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

Как кэширование связано с Core Web Vitals?

Кэширование сокращает время генерации страницы на сервере, а значит уменьшает время до первого байта (TTFB) — фундамент, на котором стоят метрики Core Web Vitals. Быстрый бэкенд и отданная из кэша (или из композита) статика напрямую улучшают LCP — время отрисовки основного контента. При этом кэш не чинит тяжёлый JavaScript, неоптимизированные картинки и сдвиги вёрстки (CLS): это отдельные фронтенд-задачи. Кэширование — необходимое, но не достаточное условие зелёных Core Web Vitals; его дополняют работой над вёрсткой и скриптами.

В чём разница между кэшем компонента и композитным кэшем?

Кэш компонента ускоряет сборку отдельного блока (меню, список товаров, баннер), но страница всё равно собирается на каждый запрос: запускается ядро, отрабатывают пролог и эпилог, склеиваются кэши компонентов. Композит (автокомпозит, HTML-кэш) кэширует уже собранную HTML-страницу целиком и отдаёт её статику мгновенно, ещё до запуска тяжёлой части ядра, а персональную динамику догружает отдельным запросом. Композит не отменяет кэш компонентов, а надстраивается над ним: грамотный кэш компонентов — фундамент, композит — финальный ускоритель.

Поделиться:

Хотите, чтобы магазин открывался мгновенно?

Настроим кэширование по уровням, теговую инвалидацию и композит, вынесем кэш в память и наладим прогрев и сброс после обмена с 1С. Рассчитаем работу по вашему магазину.

Услуга «Ускорение сайта»

Игорь Воскресенский

Команда студии B2Bsite. С 2014 года разрабатываем, ускоряем и поддерживаем интернет-магазины на 1С-Битрикс: кэширование, теговый кэш и композит, memcached и Redis, Core Web Vitals и обмен с 1С для среднего и крупного бизнеса.

← Все статьи блога