Разработка фильтра товаров на React для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка фильтра товаров на React для 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка фильтра товаров на React для 1С-Битрикс

Штатный компонент bitrix:catalog.smart.filter работает через server-side рендеринг с полной перезагрузкой страницы или AJAX-подменой HTML. При каждом изменении фильтра — HTTP-запрос, серверный рендеринг, замена блока в DOM. На каталоге в 50 000 SKU с 30+ характеристиками время ответа составляет 800–2000 мс, и это ещё без учёта времени рендеринга на фронте.

React-фильтр меняет подход: UI обновляется мгновенно, запрос к серверу отправляется с debounce 300–500 мс, результаты обновляются в фоне. Пользователь видит отклик сразу, а не ждёт round-trip до сервера.

Архитектура React-фильтра

Фильтр состоит из трёх независимых частей: компонент фильтра (чекбоксы, ренджи, сортировка), компонент каталога (список товаров, пагинация), URL-синхронизация (состояние фильтра отражается в URL для шаринга и SEO).

Состояние фильтра синхронизируется с URL через useSearchParams из React Router или нативный URLSearchParams. Это критично: пользователь должен иметь возможность скопировать URL с применёнными фильтрами.

// Хук синхронизации фильтра с URL
function useFilterState(initialFilters: FilterState) {
  const [searchParams, setSearchParams] = useSearchParams();

  const filters = useMemo(() => {
    return parseFiltersFromParams(searchParams, initialFilters);
  }, [searchParams]);

  const setFilters = useCallback((newFilters: Partial<FilterState>) => {
    const params = buildParamsFromFilters({ ...filters, ...newFilters });
    setSearchParams(params, { replace: true }); // replace, не push — не засоряем историю
  }, [filters, setSearchParams]);

  return [filters, setFilters] as const;
}

API на стороне Битрикс

Серверный endpoint принимает параметры фильтра и возвращает товары + фасетные счётчики (сколько товаров по каждому значению характеристики).

public function getProductsAction(array $filter = [], int $page = 1): array
{
    // Строим Битрикс-фильтр из параметров запроса
    $bxFilter = $this->buildBitrixFilter($filter);

    // Товары
    $result = \CIBlockElement::GetList(
        ['SORT' => 'ASC'],
        $bxFilter,
        false,
        ['nPageSize' => 24, 'iNumPage' => $page],
        ['ID', 'NAME', 'PREVIEW_PICTURE', 'DETAIL_PAGE_URL',
         'CATALOG_PRICE_1', 'PROPERTY_BRAND', 'PROPERTY_COLOR']
    );

    $products = [];
    while ($product = $result->GetNextElement()) {
        $fields = $product->GetFields();
        $props  = $product->GetProperties();
        $products[] = $this->formatProduct($fields, $props);
    }

    // Фасетные счётчики для обновления вариантов фильтра
    $facets = $this->getFacets($bxFilter, $filter);

    return [
        'products' => $products,
        'total'    => $result->SelectedRowsCount(),
        'facets'   => $facets,
    ];
}

Для фасетных счётчиков используется \Bitrix\Iblock\Component\Tools или прямые запросы к таблицам b_iblock_element_property с GROUP BY — зависит от нагрузки и объёма каталога.

Типы фильтров и их реализация

Чекбокс-группы (бренд, цвет, материал) — самый распространённый тип. Значения приходят из свойств инфоблока. На фронте — список с поиском внутри группы при большом количестве значений (20+).

Диапазон цены — ценовой слайдер с двумя ручками. Библиотека rc-slider или нативная реализация на CSS custom properties. Запрос отправляется с debounce 500 мс — иначе каждый пиксель движения слайдера триггерит запрос.

Рейтинг — звёздный рейтинг как фильтр (от N звёзд).

Размерная сетка — кнопки-переключатели. Особенность: доступность конкретного размера зависит от остатков, поэтому неактивные значения должны подсвечиваться серым, а не просто отсутствовать.

Кейс: фильтр для маркетплейса одежды

Мультивендорный каталог, ~180 000 SKU, 45 характеристик. Задача: фильтр должен работать мгновенно, поддерживать многоуровневые зависимости (выбор категории меняет доступные фильтры) и отражать состояние в URL для SEO.

Штатный SmartFilter Битрикс давал время ответа 1.4–2.1 сек, при этом фасетные счётчики пересчитывались при каждом запросе и становились узким местом.

Решение:

  1. Фасеты вынесены в отдельный кешируемый endpoint. Счётчики пересчитываются через очередь (\Bitrix\Main\Application::getInstance()->addBackgroundJob()) после изменения остатков, а не в реальном времени на каждый запрос.

  2. На фронте — optimistic UI: чекбокс отмечается мгновенно, счётчик товаров обновляется с небольшой задержкой. Пользователь не ждёт подтверждения от сервера для визуального отклика.

  3. Мобильная версия фильтра — отдельный компонент с bottom sheet (выезжает снизу). Десктоп — сайдбар. Переключение через CSS media query + React context.

  4. Пустые результаты — не белый экран, а блок с предложением расширить фильтр (убрать одну из характеристик). React анализирует, какой последний выбранный параметр даёт 0 результатов, и предлагает его убрать.

Характеристика SmartFilter React-фильтр
Время отклика на чекбокс 1400–2100 мс 0 мс (UI), 280–400 мс (данные)
Обновление счётчиков При каждом запросе Из кеша, обновление фоном
Глубина линк-шаринга Частичная Полная (все параметры в URL)
Мобильный UX Отдельная страница Bottom sheet без перехода

SEO и SSR

Фильтр на React создаёт SEO-проблему: поисковик не всегда выполняет JavaScript. Решений несколько.

SSR через отдельный рендерер — тяжело, требует Node.js-инфраструктуры рядом с Битрикс.

Prerendering — SPA рендерится через headless Chrome при краулинге. Реализуется через Prerender.io или nginx-конфиг, который определяет User-Agent бота и проксирует запрос на рендерер.

Гибридный подход (рекомендуемый): страницы с SEO-ценными фильтрами (категория + бренд) имеют статические PHP-URL, которые рендерит Битрикс. React-фильтр работает поверх этих страниц, но начальное состояние берёт из PHP-шаблона (переданный в window.__INITIAL_STATE__). Боты видят HTML, пользователи — интерактивный React.

Оптимизация производительности

Бесконечная прокрутка vs. пагинация: для мобильных — infinite scroll через IntersectionObserver, для десктопа — пагинация (SEO + возможность вернуться к конкретной странице).

Виртуализация списка при большом количестве результатов (react-virtual или @tanstack/react-virtual) — при отображении 200+ карточек без виртуализации DOM становится тяжёлым.

React Query для кеширования: переход между страницами каталога не делает повторный запрос, если данные в кеше свежие (staleTime: 30_000).

Состав работ

  • Анализ структуры каталога: характеристики, типы фильтров, объём данных
  • API-контроллер: фильтрация, пагинация, фасеты, кеширование
  • Разработка React: компоненты фильтра, каталога, синхронизация с URL
  • SEO-стратегия: prerendering или гибридный подход
  • Тестирование производительности под нагрузкой

Сроки: базовый фильтр (чекбоксы + диапазон цены) — 2–3 недели. Полнофункциональный с фасетами, мобильным UX и SEO-стратегией — 5–8 недель.