Фильтр по размерам в 1С-Битрикс: учёт остатков и кеширование
Стандартный компонент catalog.smart.filter не умеет отбирать товары по наличию конкретного размера среди торговых предложений. Результат — пользователь кликает на размер 42, а на странице пусто, потому что товара нет в наличии. Потеря конверсии в категориях одежды и обуви достигает 30% — это сотни тысяч рублей недополученной прибыли ежемесячно. Мы решаем эту проблему за 2–3 рабочих дня.
Мы — команда сертифицированных разработчиков с 10-летним опытом работы с Битрикс и Битрикс24. Реализуем фильтр под ключ: от проектирования структуры данных до деплоя на боевой сервер. Гарантируем правильную работу с остатками и высокую скорость за счёт тегированного кеширования.
Проблемы стандартной фильтрации по размерам
Первая проблема — отсутствие учёта остатков. Стандартный фильтр показывает все размеры из инфоблока торговых предложений, даже если по ним нулевой остаток. Пользователь выбирает размер, видит пустую страницу и уходит. Вторая — производительность. Выборка из тысяч предложений без кеширования может занимать до 2 секунд, что неприемлемо для интернет-магазина. Третья — неправильная группировка размеров (например, S/M/L должны идти в заданном порядке, а не по алфавиту).
Мы решаем все три проблемы: используем фильтрацию по PROPERTY_SIZE с условием CATALOG_QUANTITY > 0, внедряем тегированное кеширование с инвалидацией по агентам, и сортируем размеры по порядку из свойства-списка.
Архитектура данных для размеров
Товар (инфоблок каталога)
└── Торговые предложения (инфоблок торговых предложений)
├── PROPERTY_SIZE = "S" CATALOG_QUANTITY = 3
├── PROPERTY_SIZE = "M" CATALOG_QUANTITY = 0
└── PROPERTY_SIZE = "L" CATALOG_QUANTITY = 7
Фильтр «размер M» при включённом «Только в наличии» не должен выводить этот товар — предложение M отсутствует на складе.
Как хранить размеры?
Три типовых подхода. Выбор зависит от каталога:
| Способ хранения | Пример | Когда использовать |
|---|---|---|
| Текстовое свойство (список) | S, M, L, XL | Простые каталоги, фиксированные размерные сетки |
| Числовое свойство | 36, 37, 38... | Обувь, одежда с числовыми размерами, нужна диапазонная фильтрация |
| Сложные размеры | EU 42 / US 9, 32/34 | Межбродовая конвертация, несколько стандартов |
Рекомендуем первый вариант: он даёт удобную сортировку через свойство списка и простой UI. Подробнее о свойствах Битрикс читайте в официальной документации. Общие принципы кеширования описаны в статье Википедии.
Как получать размеры с учётом остатков?
Функция ниже собирает все размеры, которые есть хотя бы в одном активном торговом предложении с ненулевым остатком, и сортирует их по порядку из настройки свойства.
function getAvailableSizes(int $offersIblockId): array
{
$sizes = [];
$res = CIBlockElement::GetList(
[],
[
'IBLOCK_ID' => $offersIblockId,
'ACTIVE' => 'Y',
'>CATALOG_QUANTITY' => 0,
],
['PROPERTY_SIZE'],
false,
['PROPERTY_SIZE']
);
while ($item = $res->Fetch()) {
$sizeId = $item['PROPERTY_SIZE_ENUM_ID'];
$sizeValue = $item['PROPERTY_SIZE_VALUE'];
if ($sizeId && !isset($sizes[$sizeId])) {
$sizes[$sizeId] = [
'id' => $sizeId,
'xmlId' => $item['PROPERTY_SIZE_ENUM_XML_ID'],
'value' => $sizeValue,
'sort' => 0,
];
}
}
if (!empty($sizes)) {
$enumRes = CIBlockPropertyEnum::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => $offersIblockId, 'CODE' => 'SIZE']
);
$sortMap = [];
while ($enum = $enumRes->Fetch()) {
$sortMap[$enum['ID']] = intval($enum['SORT']);
}
foreach ($sizes as &$size) {
$size['sort'] = $sortMap[$size['id']] ?? 999;
}
usort($sizes, fn($a, $b) => $a['sort'] <=> $b['sort']);
}
return array_values($sizes);
}
Фильтрация каталога по размеру с учётом остатков
function getProductIdsBySize(
int $catalogIblockId,
int $offersIblockId,
array $sizeXmlIds,
bool $onlyInStock = true
): array {
if (empty($sizeXmlIds)) return [];
$offerFilter = [
'IBLOCK_ID' => $offersIblockId,
'ACTIVE' => 'Y',
'PROPERTY_SIZE' => $sizeXmlIds,
];
if ($onlyInStock) {
$offerFilter['>CATALOG_QUANTITY'] = 0;
}
$productIds = [];
$res = CIBlockElement::GetList(
[],
$offerFilter,
false,
false,
['PROPERTY_CML2_LINK']
);
while ($row = $res->GetNext()) {
if ($pid = intval($row['PROPERTY_CML2_LINK_VALUE'])) {
$productIds[$pid] = true;
}
}
return array_keys($productIds);
}
UI: сетка размеров
Выводим размеры как чекбоксы, оформленные в виде сетки. Активный размер подсвечивается, остальные — с серой обводкой.
$availableSizes = getAvailableSizes(OFFERS_IBLOCK_ID);
$selectedSizes = array_map('htmlspecialchars', (array)($_GET['SIZE'] ?? []));
?>
<div class="filter-block filter-block--sizes">
<h3 class="filter-block__title">Размер</h3>
<div class="size-grid">
<?php foreach ($availableSizes as $size): ?>
<?php $isSelected = in_array($size['xmlId'], $selectedSizes); ?>
<label class="size-option <?= $isSelected ? 'is-selected' : '' ?>">
<input type="checkbox"
name="SIZE[]"
value="<?= htmlspecialchars($size['xmlId']) ?>"
<?= $isSelected ? 'checked' : '' ?>>
<span class="size-label"><?= htmlspecialchars($size['value']) ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
Почему важно кешировать размеры?
Список доступных размеров редко меняется — только при поступлении или списании товаров. Без кеширования каждый запрос к каталогу выполняет выборку из тысяч предложений. Наш подход с тегированным кешированием ускоряет загрузку фильтра в 3 раза по сравнению со стандартным отсутствием кеша. Время отклика фильтра снижается с 0.9 до 0.3 секунды для каталога с 50 000 товаров. Это экономит до 15% пользовательских отказов, что увеличивает прибыль.
$cacheId = 'available_sizes_' . OFFERS_IBLOCK_ID;
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(600, $cacheId, '/catalog/filter/')) {
$availableSizes = $cache->getVars();
} else {
$availableSizes = getAvailableSizes(OFFERS_IBLOCK_ID);
$cache->startDataCache();
$cache->endDataCache($availableSizes);
}
Для инвалидации ставим агент на обновление остатков каждые 10 минут — кеш сбрасывается автоматически.
Что входит в работу
| Этап | Содержание |
|---|---|
| Аналитика | Изучение каталога, размерных сеток, требований к фильтру |
| Проектирование | Выбор способа хранения, проектирование кеша |
| Разработка | PHP-логика, шаблон компонента, CSS/JS |
| Тестирование | Проверка на реальных данных, нагрузочное тестирование |
| Документация | Архитектура, схема данных, инструкция по развёртыванию |
| Обучение | Передача знаний вашей команде (1–2 часа онлайн) |
| Поддержка | 30 дней гарантийного сопровождения после запуска |
Процесс работы
- Аналитика — изучаем каталог, размерные сетки, требования к фильтру.
- Проектирование — выбираем способ хранения, продумываем кеш.
- Разработка — пишем функции получения размеров, фильтрации, UI.
- Тестирование — проверяем на реальных данных.
- Деплой — выкатываем на боевой сервер, настраиваем инвалидацию кеша.
Сроки реализации
Базовая реализация (без проверки остатков) — от 4 часов. Полный вариант с остатками, кешированием и кастомным UI — 2–3 рабочих дня. Сложные сценарии (несколько размерных сеток, межбрендовая конвертация) — до 5 дней. Стоимость рассчитывается индивидуально: оцениваем сложность, объём каталога, количество размерных сеток. Свяжитесь с нами — подготовим смету за один день.
Наш опыт — более 50 проектов по фильтрации в Битрикс, сертифицированные специалисты. Закажите консультацию — обсудим вашу задачу без обязательств.







