Кеш в Битриксе — это не одна «магическая галочка», а целая система уровней: кеш компонентов, кеш данных (старое ядро и D7), тегированный и управляемый кеш, кеш ORM, HTML/композитный кеш и т.д. Правильное использование каждого вида — это половина оптимизации производительности проекта.

Ниже — практическое руководство с рабочими примерами кода.
1. Общая карта кешей в Битриксе
Основные виды кеша, с которыми вы сталкиваетесь в реальных проектах:
- Кеш компонентов
- Настраивается в параметрах компонента.
- Режимы: Авто, Авто + управляемый, Отключ.
- PHP-кеш данных
- Старое ядро — класс
CPHPCache. - Новое ядро D7 —
Bitrix\Main\Data\Cache.
- Старое ядро — класс
- Тегированный (tagged) кеш
- Позволяет привязать кеш к тегам (например,
iblock_id_5), чтобы сбрасывать его при изменении данных.
- Позволяет привязать кеш к тегам (например,
- Управляемый кеш
- Автоматически сбрасывает кеш компонентов при изменении данных, используется в режиме Авто + управляемый и при ORM-кешировании.
- Кеш ORM (D7 ORM)
- Кеш внутри запросов
DataManager::getList()через параметрcache.
- Кеш внутри запросов
- HTML/композитный кеш
- Кеширует целую страницу целиком для анонимных пользователей, используя файловое хранилище
/bitrix/html_pages/и классStatictmlCacheвнутри ядра.
- Кеширует целую страницу целиком для анонимных пользователей, используя файловое хранилище
Отдельно живут кеши опций, меню, настроек и т.п., но они в основном построены на тех же механизмах (управляемый/тегированный кеш, Data\Cache, ORM).
2. Кеш компонентов: StartResultCache и режимы Авто/Авто+управляемый
2.1. Что кешируется
Компонентный кеш — это сохранение массива $arResult и HTML-вывода шаблона на диск в /bitrix/cache/.
По сути, при включенном кешировании:
- Битрикс формирует ID кеша на базе:
- сайта, имени компонента, шаблона,
- параметров компонента,
- «внешних условий» (например, группы пользователя, если вы их учли).
- Если такой кеш уже есть и не истёк — просто выводит HTML и
$arResultиз файла. - Если нет — выполняет код компонента, позаписывает все данные, сохранит их в кеш.
2.2. Пример собственного компонента с кешем
/local/components/vendor/simple.random/class.php:
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Loader;
class SimpleRandomComponent extends CBitrixComponent
{
public function onPrepareComponentParams($params)
{
$params['CACHE_TIME'] = (int)$params['CACHE_TIME'] > 0 ? (int)$params['CACHE_TIME'] : 3600;
$params['CACHE_BY_GROUPS'] = $params['CACHE_BY_GROUPS'] === 'N' ? 'N' : 'Y';
return $params;
}
public function executeComponent()
{
global $USER;
$additionalCacheId = '';
if ($this->arParams['CACHE_BY_GROUPS'] === 'Y' && is_object($USER)) {
$additionalCacheId = $USER->GetUserGroupString();
}
if ($this->StartResultCache($this->arParams['CACHE_TIME'], $additionalCacheId)) {
// Здесь можно проверять доступ к данным, модули и т.п.
if (!Loader::includeModule('iblock')) {
$this->AbortResultCache();
ShowError('Модуль "Инфоблоки" не установлен');
return;
}
$this->arResult['RANDOM'] = rand(1, 1000);
$this->arResult['TIME'] = date('c');
// Если данные «плохие» — не кешируем
if ($this->arResult['RANDOM'] < 10) {
$this->AbortResultCache();
ShowError('Случайное число меньше 10, кеш не создаётся');
return;
}
$this->IncludeComponentTemplate();
}
}
}
/local/components/vendor/simple.random/.parameters.php:
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
$arComponentParameters = [
'PARAMETERS' => [
'CACHE_TIME' => [
'PARENT' => 'BASE',
'NAME' => 'Время кеширования (сек)',
'TYPE' => 'STRING',
'DEFAULT' => 3600,
],
'CACHE_BY_GROUPS' => [
'PARENT' => 'CACHE_SETTINGS',
'NAME' => 'Разделять кеш по группам пользователей',
'TYPE' => 'CHECKBOX',
'DEFAULT' => 'Y',
],
],
];
Шаблон компонента /local/components/vendor/simple.random/templates/.default/template.php:
<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die(); ?>
<div class="simple-random">
<div>Случайное число: <?= (int)$arResult['RANDOM']; ?></div>
<div>Сформировано: <?= htmlspecialcharsbx($arResult['TIME']); ?></div>
</div>
Режим кеширования (Авто / Авто+управляемый) задаётся уже в настройках компонента в визуальном редакторе.
3. Кеш данных старого ядра: CPHPCache
CPHPCache — класс старого ядра, который умеет кешировать массивы переменных и HTML-вывод в файловой системе (/bitrix/cache/).
3.1. Базовый пример CPHPCache
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
/** @var CMain $APPLICATION */
$cacheTime = 3600;
$cacheId = 'demo_cphpcache_example';
$cacheDir = '/demo/cphpcache';
$cache = new CPHPCache();
$data = [];
if ($cache->InitCache($cacheTime, $cacheId, $cacheDir)) {
// Читаем данные из кеша
$data = $cache->GetVars();
} elseif ($cache->StartDataCache()) {
// Эмулируем тяжёлую операцию
$data = [
'TIME' => date('c'),
'RANDOM' => rand(100, 999),
'MESSAGE' => 'Данные сгенерированы без кеша',
];
// Проверка условия, при котором кеш не нужен
if ($data['RANDOM'] < 150) {
$cache->AbortDataCache();
} else {
$cache->EndDataCache($data);
}
}
// Выводим результат
echo '<pre>';
print_r($data);
echo '</pre>';
Важно:
InitCache()— проверяет наличие и актуальность кеша.StartDataCache()— либо начинает буферизацию, либо сразу выводит кеш и возвращаетfalse.EndDataCache($vars)— сохраняет данные.AbortDataCache()— отмена сохранения кеша.
4. D7 кеш данных: Bitrix\Main\Data\Cache
Современный D7-класс Bitrix\Main\Data\Cache работает почти так же, как CPHPCache, но лучше вписывается в D7-код и поддерживает дополнительные возможности (управление из кода, динамические конфиги и т.п.).
4.1. Простой пример с Bitrix\Main\Data\Cache
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Data\Cache;
$cacheTime = 3600;
$cacheId = 'demo_d7_cache_example';
$cacheDir = '/demo/d7_cache';
$cache = Cache::createInstance();
$data = [];
if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
$data = $cache->getVars();
} elseif ($cache->startDataCache()) {
$data = [
'TIME' => date('c'),
'RANDOM' => rand(1, 1000),
'MESSAGE' => 'Сформировано с использованием D7 Cache',
];
if ($data['RANDOM'] === 777) {
// Вдруг нам не нравится это число :)
$cache->abortDataCache();
} else {
$cache->endDataCache($data);
}
}
echo '<pre>';
print_r($data);
echo '</pre>';
4.2. Пример кеширования тяжёлого запроса к инфоблоку на D7
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Data\Cache;
use Bitrix\Main\Loader;
$iblockId = 5;
$cacheTime = 600;
$cacheId = 'iblock_' . $iblockId . '_top5';
$cacheDir = '/demo/iblock_top5';
$cache = Cache::createInstance();
$arResult = [
'ITEMS' => [],
];
if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
$arResult = $cache->getVars();
} elseif ($cache->startDataCache()) {
if (!Loader::includeModule('iblock')) {
$cache->abortDataCache();
} else {
$res = CIBlockElement::GetList(
['ACTIVE_FROM' => 'DESC'],
[
'IBLOCK_ID' => $iblockId,
'ACTIVE' => 'Y',
],
false,
['nTopCount' => 5],
['ID', 'NAME', 'DETAIL_PAGE_URL', 'ACTIVE_FROM']
);
while ($item = $res->GetNext()) {
$arResult['ITEMS'][] = $item;
}
if (empty($arResult['ITEMS'])) {
$cache->abortDataCache();
} else {
$cache->endDataCache($arResult);
}
}
}
if (!empty($arResult['ITEMS'])) {
echo '<ul>';
foreach ($arResult['ITEMS'] as $item) {
echo '<li>';
echo '<a href="' . htmlspecialcharsbx($item['DETAIL_PAGE_URL']) . '">';
echo htmlspecialcharsbx($item['NAME']);
echo '</a>';
if (!empty($item['ACTIVE_FROM'])) {
echo ' (' . htmlspecialcharsbx($item['ACTIVE_FROM']) . ')';
}
echo '</li>';
}
echo '</ul>';
}
5. Тегированный кеш и управляемый кеш
5.1. Идея тегированного кеша
Тегированный кеш (Tagged Cache) позволяет «подписать» кеш тегами (например, iblock_id_5), а при изменении данных ядро Битрикс сбрасывает все кеши, связанные с этим тегом.
Это основа управляемого кеша — именно поэтому в режиме Авто + управляемый кеш компонентов обновляется сразу после изменения инфоблока, меню и т.п.
5.2. Пример: тегированный кеш списка новостей инфоблока
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Application;
use Bitrix\Main\Data\Cache;
use Bitrix\Main\Loader;
$iblockId = 5;
$cacheTime = 3600;
$cacheId = 'news_list_iblock_' . $iblockId;
$cacheDir = '/demo/tagged_news_list';
$cache = Cache::createInstance();
$taggedCache = Application::getInstance()->getTaggedCache();
$arResult = [
'ITEMS' => [],
];
if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
$arResult = $cache->getVars();
} elseif ($cache->startDataCache()) {
if (!Loader::includeModule('iblock')) {
$cache->abortDataCache();
} else {
$taggedCache->startTagCache($cacheDir);
// Привязываем кеш ко всему инфоблоку
$taggedCache->registerTag('iblock_id_' . $iblockId);
$res = CIBlockElement::GetList(
['ACTIVE_FROM' => 'DESC'],
[
'IBLOCK_ID' => $iblockId,
'ACTIVE' => 'Y',
],
false,
['nTopCount' => 10],
['ID', 'NAME', 'DETAIL_PAGE_URL', 'ACTIVE_FROM']
);
while ($item = $res->GetNext()) {
$arResult['ITEMS'][] = $item;
}
if (empty($arResult['ITEMS'])) {
$taggedCache->abortTagCache();
$cache->abortDataCache();
} else {
$taggedCache->endTagCache();
$cache->endDataCache($arResult);
}
}
}
if (!empty($arResult['ITEMS'])) {
echo '<ul>';
foreach ($arResult['ITEMS'] as $item) {
echo '<li>';
echo '<a href="' . htmlspecialcharsbx($item['DETAIL_PAGE_URL']) . '">';
echo htmlspecialcharsbx($item['NAME']);
echo '</a>';
if (!empty($item['ACTIVE_FROM'])) {
echo ' (' . htmlspecialcharsbx($item['ACTIVE_FROM']) . ')';
}
echo '</li>';
}
echo '</ul>';
}
Когда вы добавите/измените/удалите элементы в инфоблоке $iblockId, ядро запустит механизм сброса тегированного кеша по тегу iblock_id_{$iblockId}, и ваш кеш пересоздастся.
5.3. Управляемый кеш через Application::getInstance()->getManagedCache()
Управляемый кеш (ManagedCache) в D7 можно получить так:
<?php
use Bitrix\Main\Application;
/** @var \Bitrix\Main\Data\ManagedCache $managedCache */
$managedCache = Application::getInstance()->getManagedCache();
У него есть методы read, get, set, clean. Пример ручного кеша настроек (вместо частых запросов к БД):
<?php
use Bitrix\Main\Application;
use Bitrix\Main\Data\ManagedCache;
use Bitrix\Main\Loader;
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
/** @var ManagedCache $managedCache */
$managedCache = Application::getInstance()->getManagedCache();
$cacheTime = 3600;
$cacheId = 'custom_settings_demo';
if ($managedCache->read($cacheTime, $cacheId)) {
$settings = $managedCache->get($cacheId);
} else {
$settings = [];
if (Loader::includeModule('main')) {
// Здесь вы могли бы считать свои настройки из БД, HL-блока и т.п.
$settings = [
'ENABLE_FEATURE' => 'Y',
'MAX_ITEMS' => 20,
];
}
$managedCache->set($cacheId, $settings);
}
echo '<pre>';
print_r($settings);
echo '</pre>';
Очистить такой кеш можно, например, при сохранении настроек:
<?php
use Bitrix\Main\Application;
$managedCache = Application::getInstance()->getManagedCache();
$managedCache->clean('custom_settings_demo');
6. Кеш ORM (D7 ORM cache)
ORM-запросы в Битрикс D7 поддерживают встроенный кеш через ключ cache в параметрах getList() / getRow().
6.1. Пример кеша ORM-запроса
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\Loader;
use Bitrix\Main\UserTable;
if (!Loader::includeModule('main')) {
ShowError('Модуль "main" не найден');
return;
}
$result = UserTable::getList([
'select' => ['ID', 'LOGIN', 'NAME', 'LAST_NAME'],
'filter' => [
'=ACTIVE' => 'Y',
],
'order' => [
'ID' => 'ASC',
],
'limit' => 50,
'cache' => [
'ttl' => 600, // Время жизни кеша в секундах
'cache_joins' => true, // Кешировать ли запросы с JOIN'ами
],
]);
$users = [];
while ($user = $result->fetch()) {
$users[] = $user;
}
echo '<pre>';
print_r($users);
echo '</pre>';
По умолчанию для ORM можно задать глобальные TTL и поведение кеша через параметр cache_flags в /bitrix/.settings.php, где управляемый кеш используется как хранилище.
7. HTML-кеш и композитный сайт
HTML-кеш (статический кеш страниц) — это кеширование полностью собранного HTML-ответа. В Битриксе композитный режим опирается на класс StaticHtmlCache, который пишет данные в файловую систему и, при необходимости, в Memcached. Разработчики обычно не используют этот класс напрямую — всё управляется из настроек и через API композитного сайта.
Файлы HTML-кеша живут в /bitrix/html_pages/.
7.1. Динамические области в шаблонах (композитный сайт)
Чтобы часть страницы не попадала в HTML-кеш, используются динамические области (frame):
<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die(); ?>
<div class="header-cart">
<?php
/** @var CBitrixComponentTemplate $this */
$frame = $this->createFrame()->begin();
?>
<span class="header-cart__count">
<?= (int)$arResult['CART_COUNT']; ?>
</span>
<?php
$frame->beginStub();
?>
<span class="header-cart__count">0</span>
<?php
$frame->end();
?>
</div>
- Всё, что внутри
begin()/end()— подгружается динамически (ajax-фрагмент). beginStub()— что увидит пользователь до загрузки динамической части.
8. Где физически лежит кеш
Полезно понимать, что и куда пишет Битрикс:
/bitrix/cache/- Некачируемый (unmanaged) кеш, кеш компонентов, Data\Cache, CPHPCache по умолчанию.
/bitrix/managed_cache/- Управляемый кеш (
ManagedCache), кеш ORM, кеш различных системных сущностей.
- Управляемый кеш (
/bitrix/html_pages/- HTML-/композитный кеш страниц.
- Папки вида
/bitrix/managed_cache/MYSQL/orm_%имя_таблицы%/- ORM-кеш по SQL-запросам (ключ —
md5(sql)).
- ORM-кеш по SQL-запросам (ключ —
9. Какой кеш когда использовать
Коротко:
- Компонентный кеш
- Для всего, что выводится через компоненты (каталог, новости, списки и т.п.).
- Всегда включайте режим Авто + управляемый, если данные меняются относительно редко, а производительность важна.
- CPHPCache / Data\Cache
- Для сложных кастомных выборок, сниппетов в шаблонах, старого кода.
- На новых проектах используйте
Bitrix\Main\Data\Cache.
- Тегированный + ManagedCache
- Когда нужно умно сбрасывать кеш по изменениям данных: инфоблоки, HL-блоки, собственные сущности.
- ORM cache
- Для повторяющихся тяжёлых ORM-запросов, где вы не хотите вручную управлять ID кеша.
- HTML/композит
- Для публичной части сайта, где много анонимного трафика; особенно для страниц с тяжёлым рендером.
10. Практические советы и анти-паттерны
- Не ставьте слишком короткий TTL, если используете управляемый кеш.
Для режима Авто + управляемый можно ставить большие значения TTL (до года), потому что кеш сбрасывается не по времени, а по событию изменения данных.
- Формируйте
cacheIdиз всех параметров, влияющих на результат.Это касается и CPHPCache/Data\Cache, и компонентного кеша (дополнительный ID).
- Не кешируйте то, что зависит от пользователя, без разделения по группам или ID.
Например, корзина, личный кабинет — либо не кешируются, либо кешируются с учётом ID пользователя.
- Всегда предусмотрите возможность сбросить кеш программно.
Например, отдельный админский обработчик, который вызывает
clean,cleanDir,clearCacheдля нужных путей. - Следите за размером
/bitrix/cache/и/bitrix/managed_cache/.При неправильной стратегии TTL и агрессивном кешировании эти каталоги могут разрастаться на гигабайты.