Кэш — главный друг быстрого каталога и его же главный источник боли, когда речь заходит о ценах и остатках. Закэшируешь страницу целиком — и получишь мгновенную отдачу, но покупатель увидит вчерашнюю цену и остаток «в наличии» у товара, который уже распродан. Не будешь кэшировать — каждая карточка бьёт по базе, и под нагрузкой сайт ложится. Задача — не выбрать одно из двух, а разделить контент так, чтобы статика летала из кэша, а цена и остаток оставались честными.
В этой статье разберём кэш-стратегии для каталога с динамичными ценами и остатками на 1С-Битрикс: композитный сайт, теговый и управляемый кэш, кэш по ключу для B2B-цен, инвалидацию при обмене с 1С и выбор бэкенда. Настройку такой архитектуры мы делаем в рамках аудита и оптимизации 1С и производительности каталога.
Коротко
- Не кэшируйте страницу целиком: разделите статику (описание, фото) и динамику (цена, остаток, корзина).
- Композитный сайт отдаёт статику мгновенно, а персональную цену и остаток догружает отдельно.
- Используйте теговый (управляемый) кэш с инвалидацией по событию, а не кэш по таймеру.
- Свяжите инвалидацию с обменом CommerceML, чтобы при обновлении товара сбрасывался только его кэш.
Конфликт скорости и актуальности
В основе всей темы лежит один конфликт: кэш ускоряет сайт ровно потому, что отдаёт заранее посчитанный результат, не пересчитывая его каждый раз. Но цена и остаток — это как раз то, что меняется, и «заранее посчитанное» быстро устаревает. Чем агрессивнее кэш, тем выше риск показать неактуальные данные.
Наивные крайности не работают. Кэшировать всё целиком — значит регулярно врать покупателю о цене и наличии. Не кэшировать ничего — значит класть базу под нагрузкой и терять в скорости, а с ней и в конверсии и в позициях. Правильное решение всегда посередине: разное содержимое кэшируется по-разному, с разной длительностью и разной инвалидацией.
Что именно меняется часто
Прежде чем выбирать стратегию, надо разложить содержимое карточки и каталога по частоте изменений. Это основа всех дальнейших решений.
| Данные | Частота изменений | Стратегия |
|---|---|---|
| Название, описание, фото | Редко | Долгий кэш |
| Характеристики, категории | Редко | Долгий кэш, теги |
| Базовая цена | Периодически | Теговый кэш |
| Персональная цена клиента | Зависит от группы | Кэш по ключу / динамика |
| Остаток на складе | Часто | Короткий кэш / динамика |
| Кнопка в корзину, статус | Каждый запрос | Вне кэша |
Видно главное: большая часть карточки меняется редко и прекрасно кэшируется надолго, а «проблемные» — это цена и остаток. Именно на них и направлены специальные приёмы, а не на страницу целиком.
Разделяй статику и динамику
Фундаментальный принцип — разделение контента по изменчивости. Страница перестаёт быть монолитом и распадается на слои, каждый со своим режимом кэширования.
- Статичный слой. Разметка, описание, фото, характеристики — кэшируются надолго и меняются редко.
- Полудинамичный слой. Базовая цена, категорийные блоки — теговый кэш с инвалидацией по событию.
- Динамичный слой. Персональная цена, остаток, корзина — выносятся из кэша или обновляются отдельно.
Такое разделение даёт лучшее из двух миров: пользователь мгновенно видит основную страницу из кэша, а изменчивые данные приходят точечно и всегда актуальны. Ключевой навык здесь — правильно провести границу между слоями, чтобы в статичный кэш случайно не попало то, что должно быть динамическим.
Композитный сайт для каталога
Штатный инструмент Битрикса для этого разделения — композитный сайт. Он разбивает страницу на статичную часть, отдаваемую почти мгновенно, и динамическую, которая догружается отдельным запросом после отрисовки.
Для каталога с меняющимися ценами это идеальный шаблон. Пользователь сразу видит структуру страницы, фото и описание из композитного кэша — время до первого контента минимально. А персональная цена, актуальный остаток и состояние корзины приходят следом динамическим запросом. В результате сайт кажется мгновенным, но не показывает устаревших цен.
Композитный сайт — большая отдельная тема: как его настраивать и где подводные камни, мы подробно разбираем в статье про хостинг и инфраструктуру BitrixVM, где композит работает в связке с правильно настроенным окружением.
Теговый и управляемый кэш
Второй ключевой инструмент — управляемый (теговый) кэш. Обычный кэш живёт по таймеру: задал время жизни (TTL) и ждёшь его истечения. Для цен и остатков это плохо: TTL либо слишком длинный (данные устаревают), либо слишком короткий (кэш не даёт выигрыша).
Теговый кэш устроен иначе. Каждый закэшированный блок помечается тегами — например, идентификатором товара или инфоблока. При изменении товара сбрасываются только кэши с соответствующим тегом, а не по таймеру и не весь каталог. Это точечная инвалидация по событию: данные обновляются ровно тогда, когда реально изменились.
- Тег на товар. Кэш карточки и её вхождений в списки помечается ID товара.
- Тег на инфоблок. Крупные изменения структуры сбрасывают связанный раздел.
- Событие обмена. Обновление цены/остатка при обмене сбрасывает нужные теги.
Работа с кэшем и данными в современном Битриксе строится через D7 — как это устроено, мы разбираем в статье про D7 ORM в Битрикс, где теговый кэш встроен в слой доступа к данным.
Кэш по ключу для B2B-цен
Отдельная головная боль — персональные цены. В B2B у каждой группы клиентов своя цена, а иногда цена зависит от договора конкретного контрагента. Кэшировать «одну цену на всех» тут нельзя.
Решений два, и обычно их комбинируют. Первое — кэш по ключу: в ключ кэша включается группа пользователя или тип цены, тогда для каждой группы держится свой закэшированный вариант. Это работает, пока групп немного. Второе — вынос персональной цены в динамическую область (композит или отдельный AJAX-вызов), чтобы не плодить кэш под каждого клиента и гарантированно не показать чужую цену.
Для по-настоящему индивидуальных цен второй подход надёжнее: цену конкретного авторизованного клиента считают на лету в динамике, а кэшируют только то, что общее для группы. Тему цен по группам мы подробнее раскрываем в материалах по B2B-каталогу.
Инвалидация при обмене с 1С
Всё построение кэша держится на одном критичном моменте — корректной инвалидации при обмене с 1С. Именно обмен CommerceML регулярно приносит новые цены и остатки, и после каждого обновления связанный кэш должен сброситься.
Идеальная картина: обмен затрагивает только изменившиеся товары и сбрасывает ровно их теги кэша. Тогда всё остальное остаётся закэшированным, а обновлённые позиции пересчитываются. Проблема начинается, когда обмен помечает «изменённым» весь каталог целиком — тогда кэш сбрасывается полностью при каждой выгрузке и теряет всякий смысл, а сайт постоянно пересчитывает страницы под нагрузкой.
Как строить надёжный и частичный обмен, а также безопасно принимать события от внешних систем, мы разбираем в статье про REST, вебхуки и безопасность в Битрикс.
Бэкенды кэша: файлы, Memcached, Redis
Где физически хранится кэш — тоже влияет на скорость и на то, насколько быстро отрабатывает инвалидация. У каждого бэкенда свои сильные стороны.
| Бэкенд | Плюсы | Минусы |
|---|---|---|
| Файловый | Прост, не требует сервисов | Медленная инвалидация, не для кластера |
| Memcached | Быстрый, in-memory, теги | Данные не переживают перезапуск |
| Redis | Быстрый, гибкий, общий на кластер | Требует настройки и памяти |
Для небольшого сайта файлового кэша может хватить, но на нагруженном каталоге с частой инвалидацией и несколькими серверами почти всегда выбирают Memcached или Redis: они быстрее и умеют держать общий кэш для всего кластера. Выбор бэкенда — часть общей настройки инфраструктуры под нагрузку.
Остаток как самая изменчивая величина
Остаток — самое сложное для кэша: он меняется от каждой продажи и каждого обмена, и именно на нём чаще всего «врут» плохо настроенные сайты. Для него применяют самые короткие и точечные стратегии.
- Короткий управляемый кэш. Остаток держат в кэше с инвалидацией по событию продажи и обмена, а не по длинному таймеру.
- Вынос в динамику. На карточке остаток запрашивают отдельным быстрым вызовом при загрузке.
- Градация вместо точного числа. Часто достаточно показать «много / мало / под заказ», а не точное количество — это стабильнее и меньше вводит в заблуждение.
- Резервы. Учитывайте зарезервированное под другие заказы, чтобы не показывать доступным то, что уже кому-то обещано.
Показывать точный остаток до штуки на карточке под высокой нагрузкой — почти всегда лишнее: он мгновенно устаревает. Градация надёжнее и для покупателя понятнее.
Проверка наличия при оформлении
Каким бы хорошим ни был кэш, есть момент, где на актуальность полагаться нельзя ни в коем случае — это оформление заказа. Между просмотром карточки и нажатием «Оформить» товар мог закончиться, поэтому финальную доступность проверяют заново.
Практика такая: на витрине допустимо показывать чуть «загрублённый» кэшированный остаток ради скорости, но в момент добавления в корзину и особенно при оформлении наличие проверяется по актуальным данным. Так вы не тормозите каталог ради точности до штуки, но и не продаёте то, чего уже нет. Это разделение ответственности между «быстрой витриной» и «строгим оформлением» — важная часть архитектуры.
Частые ошибки
- Кэшируют страницу целиком. Цена и остаток попадают в общий кэш и устаревают или показываются чужими.
- Кэш по таймеру для остатков. TTL либо врёт, либо не даёт выигрыша — вместо тегового кэша.
- Обмен сбрасывает весь кэш. Полная выгрузка помечает изменённым весь каталог, кэш всегда холодный.
- Персональная цена в статике. Цена одной группы попадает в композитный кэш и видна другим.
- Точный остаток на витрине. Число до штуки мгновенно устаревает под нагрузкой.
- Нет проверки при оформлении. Полагаются на кэшированный остаток и продают отсутствующее.
- Файловый кэш под большой нагрузкой. Медленная инвалидация и отсутствие общего кэша на кластере.
Чек-лист внедрения
- Контент разложен по изменчивости. Ясно, что статично, что полудинамично, что динамично.
- Композит настроен. Статика мгновенна, персональная цена и остаток — в динамике.
- Теговый кэш включён. Блоки помечены тегами товаров и инфоблоков, инвалидация по событию.
- B2B-цены решены. Кэш по ключу группы или вынос персональной цены в динамику.
- Обмен частичный. Обновляются только изменённые товары, сбрасываются только их теги.
- Бэкенд под нагрузку. Memcached или Redis на нагруженном каталоге и кластере.
- Остаток загрублён на витрине. Градация вместо точного числа, короткий кэш.
- Проверка при оформлении. Финальная доступность сверяется по актуальным данным.
Вывод
Кэшировать каталог с динамичными ценами и остатками можно и нужно — вопрос лишь в том, чтобы не кэшировать всё одним куском. Разделите контент на статичный, полудинамичный и динамичный слои, отдайте статику мгновенно через композит, а цену и остаток держите на теговом кэше с точечной инвалидацией или выносите в динамику.
Критичная связка — инвалидация при обмене с 1С: обмен должен обновлять только изменённые товары и сбрасывать только их теги, иначе кэш теряет смысл. Добавьте правильный бэкенд под нагрузку и обязательную проверку наличия при оформлении — и вы получите каталог, который одновременно летает и не врёт покупателю о цене и наличии.