Как ускорить каталог интернет-магазина на 1С-Битрикс

Схема компонентов, влияющих на скорость каталога Битрикс
Содержание 21 разделов

Разбираем, что именно тормозит каталог, какие пороги деградации подтверждены тестами и какие решения работают на практике

Почему каталог на Битрикс начинает тормозить

Жалоба звучит обычно одинаково: страница раздела каталога или результат применения фильтра грузится по 3–10 секунд, хотя ещё несколько месяцев назад открывалась мгновенно. Чаще всего это происходит не из-за самой CMS, а из-за роста данных: в каталог добавили новые свойства, торговые предложения, типы цен или склады, а архитектура и настройки остались прежними.

Практический аудит производительности обычно выявляет одни и те же проблемы: слишком большое количество товаров в одном разделе, избыточно сложную структуру каталога и непоследовательную навигацию — это одновременно замедляет загрузку и портит юзабилити [17]. Отдельная категория проблем — включённые, но неиспользуемые модули: AD/LDAP-интеграция, Push & Pull, вебмессенджер и десяток других компонентов, которые есть в системе «на всякий случай» и продолжают расходовать ресурсы сервера [3].

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

Как устроена скорость каталога в Битрикс — простыми словами

Чтобы понимать, что чинить, полезно разобраться, из каких «слоёв» складывается генерация страницы каталога.

Инфоблоки, торговые предложения и откуда берётся нагрузка

Товары и разделы каталога в Битриксе хранятся в информационных блоках (инфоблоках). У товара может быть множество торговых предложений (SKU) — вариантов по цвету, размеру, комплектации — и у каждого SKU свой набор свойств, цен и остатков на складах. Чем больше свойств, типов цен и складов, тем больше связанных таблиц СУБД нужно поднять при каждом обращении к странице каталога.

Классический способ получить данные — метод CIBlockElement::GetList(), знакомый с первых версий системы. Он остаётся рабочим и «незаменимым в компонентах 2.0», но при сложных выборках его постепенно вытесняет более новый ORM-слой D7 (Bitrix\Iblock\Elements\ElementTable::getList), который читабельнее и лучше интегрирован с остальным ядром — кешированием и событийной моделью [9][10]. При этом разница в скорости между старым и новым API в большинстве сценариев минимальна: оба генерируют похожие по структуре SQL-запросы, а миф о том, что ORM «всегда медленнее» из-за оверхеда, не подтверждается на типовых задачах [10].

Композитный режим и кеширование компонентов

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

Дополнительный уровень — автокеширование компонентов, при котором динамические блоки страницы получают встроенное управление кешем: компоненты в режиме «Авто + Управляемое» сами обновляют кеш по истечении заданного времени или при изменении данных [4]. Общая рекомендация архитекторов Битрикса звучит так: проектировать логику так, чтобы даже без кеша число запросов и их сложность были минимальны, а для тяжёлых выборок создавать специфические для проекта индексы в БД [2].

Фасетный индекс и умный фильтр

Умный фильтр (bitrix:catalog.smart.filter) — компонент, который строит динамические фильтры по свойствам и ценам, не перезагружая страницу. Под его капотом — отдельная таблица «фасетного индекса» (Property Index), в которой для каждого раздела и каждого элемента заранее сохранены доступные значения свойств и типов цен [11]. Индекс включается в работу автоматически при выполнении сразу нескольких условий: фильтрация идёт по свойствам с оператором AND, в фильтре указан ID инфоблока, раздел (SECTION_ID) и активность элементов [11]. Пока фасетный индекс невелик, он ускоряет фильтрацию в разы: по опыту внедрений на базе стороннего модуля Sotbit, скорость подбора товаров вырастает в 3–4 раза за счёт того, что содержимое каталога один раз индексируется в фасет, а дальнейшая фильтрация идёт уже по нему [16].

Что на практике убивает производительность каталога

Результаты нагрузочного тестирования: цифры

Наиболее показательное независимое исследование — серия нагрузочных тестов на «1С-Битрикс: Управление сайтом» (редакция «Бизнес»), проведённых на сервере с 6-ядерным процессором 3,8 ГГц и 10 Гб ОЗУ с помощью Яндекс.Танка [11]. Тестировали четыре типа страниц: детальную карточку товара, список товаров с умным фильтром, страницу применённого фильтра и страницу поиска, при полностью отключённом кешировании [11].

Ключевые наблюдения:

  • Рост числа типов цен и складов почти не влияет на список и фильтр каталога, но заметно сказывается на скорости корзины и оформления заказа [11].
  • Рост числа свойств SKU почти не увеличивает количество SQL-запросов, но резко увеличивает время их выполнения именно на страницах списка товаров и применённого фильтра — виноват тяжёлый запрос компонента умного фильтра, который строит фасеты [11].
  • При включённом кешировании время генерации всех проверяемых страниц не превышало 0,2 секунды — разница с «холодным» режимом достигала десятков раз [11].

Отдельно был поставлен стресс-тест на каталоге в 100 000 товаров: время генерации страницы списка выросло до 32,8 секунды, а страницы с применённым фильтром — до 38,8 секунды на некешированном стенде [11]. Это не значит, что Битрикс «не тянет» такие объёмы — это иллюстрация того, что происходит, если оставить конфигурацию по умолчанию без адаптации под объём данных.

Разросшийся фасетный индекс

Главная находка исследования — прямая связь между размером таблицы фасетного индекса и деградацией скорости. При добавлении в тестовый каталог дополнительных свойств размер таблицы фасетов вырос с ~11 до ~18 млн записей, и именно это, а не рост числа товаров как таковой, стало причиной резкого падения скорости: при JOIN с таблицей такого размера MySQL начинает работать существенно медленнее [11]. Ориентировочный порог, после которого начинается заметная деградация — около 10 млн записей в таблице фасетов; количество записей можно оценить по формуле: число разделов × (число товаров × число свойств товаров) + (число SKU × (число свойств SKU + число типов цен)) [11].

Похожая проблема касается и других таблиц: с ростом типов цен разрастается b_catalog_price, с ростом числа складов — b_catalog_store_product, а с ростом числа свойств элементов (если инфоблоки не переведены в режим 2.0) — b_iblock_element_property [11]. Первые две таблицы влияют в основном на корзину и оформление заказа, а разрастание таблицы свойств ощущается на всём пути пользователя по сайту [11].

Отдельно стоит проблема поиска: собственный поисковый механизм Битрикса использует морфологический стемминг, а таблица b_search_content_stem при индексации 50 000 товаров может содержать около 29 млн записей — из-за JOIN с ней первый (некешированный) поисковый запрос выполняется около 8 секунд, тогда как кешированная страница отдаётся быстрее секунды [11].

Устаревший API и лишние запросы к БД

Отдельная категория проблем — не архитектурная, а чисто программистская: код, написанный без учёта нагрузки. Типичный анти-паттерн — выборка элементов инфоблока по одному в цикле через CIBlockElement::GetByID, вместо того чтобы собрать список ID и получить все элементы одним запросом через GetList с фильтром по массиву идентификаторов [25]. При тысячах товаров в каталоге такая разница превращается из незаметной в критичную: один запрос вместо тысячи меняет время генерации страницы на порядки.

Российская специфика: хостинг, требования, инструменты

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

Официальные технические требования к окружению прямо рекомендуют использовать PHP-акселератор — предпочтительно OPcache, входящий в состав PHP начиная с версии 5.5; более старые решения (eAccelerator, XCache) либо не поддерживаются, либо требуют специфической настройки [12]. Для интернет-магазина с десятками тысяч SKU и трафиком от нескольких тысяч посетителей в сутки провайдеры, специализирующиеся на хостинге Битрикс, рекомендуют связку SSD/NVMe-дисков, достаточного объёма RAM и CPU, включённого Redis или Memcached для кеширования и настроенной связки nginx + Apache (либо nginx + PHP-FPM) [13]. На практике серверные настройки для Битрикса типично включают, среди прочего, увеличение max_input_vars до 10 000, отключение opcache.revalidate_freq, настройку pm.max_children в PHP-FPM под ожидаемую нагрузку и подключение MySQL-модулей и расширений (mysqli, gd, curl, mbstring) [14].

Отдельная удобная точка входа для владельца сайта — встроенный «Монитор производительности» в административной панели, который выдаёт агрегированную оценку скорости окружения; для оценки скорости страниц снаружи дополнительно используют Google PageSpeed Insights, GTmetrix и WebPageTest [18]. Для нагрузочного тестирования в российской практике распространён инструмент Яндекс.Танк — именно он использовался в независимом тестировании производительности каталога, о котором речь шла выше [11].

Важно и то, что часть инфраструктурных решений специфична именно для Битрикс-проектов: например, технология Push & Pull (веб-мессенджер, онлайн-уведомления) требует отдельного модуля nginx (push-stream-module), который настраивается наравне с php.ini и my.cnf в типовом Битрикс-окружении (BitrixVM) [14].

Варианты решения — от простого к сложному

Настройки без доработки кода

Первый и часто самый недооценённый шаг — аудит того, что уже включено. По опыту консалтинга, отключение неиспользуемых модулей (веб-аналитика, документооборот, интеграция с Битрикс24, конструктор отчётов и другие, если они фактически не задействованы) может само по себе дать прирост производительности на 10–20 пунктов индекса «Монитора производительности» [3]. Дополнительно стоит:

  • Убедиться, что композитный режим включён и не кеширует административную часть [1].
  • Перевести компоненты каталога в режим автокеширования, где это уместно [4].
  • Пересмотреть состав свойств, задействованных в умном фильтре: действительно ли все они нужны бизнесу — это напрямую влияет на размер фасетного индекса [11].
  • Ограничить число типов цен разумным диапазоном (на практике эксперты не рекомендуют делать больше 10–20 типов цен, для более гибкого ценообразования лучше подходят кастомные скидки) и не плодить лишние склады без необходимости [11].
  • Индексировать в поиске только те свойства и поля, которые реально нужны — иначе таблицы стемминга становятся источником замедления [11].

Доработка структуры данных (Инфоблоки 2.0, Highload-блоки)

Если проблема не в настройках, а в объёме данных, следующий шаг — изменение способа хранения свойств. Инфоблоки 2.0 переносят свойства из построчного хранения (таблица b_iblock_element_property) в отдельные столбцы собственной таблицы каждого инфоблока, что резко снижает число обрабатываемых строк при выборках [11]. У этого решения есть жёсткое ограничение: перевод в режим 2.0 возможен только если у инфоблока меньше 50 свойств — из-за лимитов MySQL на количество колонок в таблице [11]. После миграции обязательно нужно вручную создавать MySQL-индексы для колонок со связями (например, для свойства привязки SKU к родительскому товару) — без этого индекса производительность может даже упасть, а не вырасти [11].

Для случаев, когда часть свойств используется редко или нужна для хранения дополнительных, не-каталожных данных, применяют Highload-блоки — модуль, созданный специально для больших объёмов на новом ядре D7 [8]. Каждый Highload-блок — это отдельная таблица со своими индексами, а работа с данными идёт через унифицированный ORM-интерфейс [6]. При проектировании таких блоков важно не забывать создавать индексы под поля, по которым идёт фильтрация, и использовать кеширование результатов выборки при больших объёмах данных [7].

Внешние поисковые движки для больших каталогов

Когда каталог вырастает до сотен тысяч товаров или миллионов SKU, а базовая оптимизация (сервер, MySQL, кеширование, структура инфоблоков) уже выполнена, стандартные компоненты каталога и фильтра всё равно становятся узким местом — они универсальны, но генерируют много SQL-запросов и плохо масштабируются на таких объёмах [11]. В подобных проектах на практике применяют два подхода:

  • Вынос малоиспользуемых или узкоспециализированных свойств в отдельные Highload-блоки и переход на инфоблоки 2.0 — это уменьшает размер фасетного индекса и ускоряет фильтрацию [11].
  • Перенос фильтрации и поиска в специализированные внешние системы — Elasticsearch, OpenSearch или Meilisearch. Такой переход требует полной переработки компонентов фильтра, поиска и страницы раздела, но снимает нагрузку с основной базы данных и заметно ускоряет отклик [11].

Отдельная точечная доработка для каталогов с высокой частотой обновления цен и остатков — собственная реализация кеша детальных страниц товара. Штатный тегированный кеш Битрикса устроен так, что при изменении любого элемента инфоблока сбрасывается кеш всех компонентов, привязанных к этому инфоблоку — то есть изменение одного товара обнуляет кеш детальных страниц всех остальных товаров каталога. Кастомный кеш, который сбрасывается только при обновлении конкретного элемента, устраняет этот эффект [11].

Практические этапы работы

  1. Диагностика. Снять показатели «Монитора производительности» Битрикса, посмотреть на реальные времена генерации ключевых страниц каталога (список, фильтр, карточка товара, поиск) с включённым и выключенным кешем, оценить число SQL-запросов на странице.
  2. Аудит окружения. Проверить версию PHP, наличие и настройки OPcache, конфигурацию MySQL, включённые модули Битрикса, состояние композитного режима.
  3. Быстрые победы. Отключить неиспользуемые модули, включить композитный режим и автокеширование там, где это уместно, устранить очевидно неоптимальные запросы (циклы с точечными выборками вместо пакетных).
  4. Оценка структуры каталога. Посчитать примерный размер таблицы фасетного индекса по формуле выше, оценить число свойств, типов цен и складов относительно фактических бизнес-потребностей.
  5. Точечные доработки. При необходимости — перевод инфоблоков в режим 2.0 с обязательной проверкой индексов, вынос части свойств в Highload-блоки, кастомизация кеша детальных страниц.
  6. Архитектурные изменения. Для по-настоящему больших каталогов — вынос поиска и фильтрации во внешний поисковый движок с переработкой соответствующих компонентов.
  7. Контрольное нагрузочное тестирование. Повторный прогон нагрузочных сценариев (например, через Яндекс.Танк) на новой конфигурации, чтобы подтвердить результат цифрами, а не ощущениями.

Ограничения, ошибки и риски

  • Кеш маскирует проблему, а не решает её. Если тесты показывают хорошее время только с включённым кешем, а без него страница генерируется десятки секунд, любой сброс кеша (обновление цен, массовый импорт из 1С) временно обрушит производительность для реальных посетителей [11].
  • Инфоблоки 2.0 подходят не всем. Жёсткий лимит в 50 свойств и обязательная переиндексация делают этот путь неприменимым для каталогов с очень широкой номенклатурой характеристик без предварительного пересмотра модели данных [11].
  • Переход на D7-ORM — не автоматическое ускорение. Разница в скорости между старым API и D7 в типовых сценариях минимальна; выигрыш даёт не сама смена API, а грамотное построение выборок и постепенная миграция без разрушения существующей логики [9][10].
  • Внешний поисковый движок — это разработка, а не настройка. Перенос фильтрации на Elasticsearch/OpenSearch требует переписывания компонентов каталога, фильтра и страницы поиска — это полноценный проект, а не однодневная доработка [11].
  • Рост типов цен и складов бьёт по другим сценариям. Даже если список товаров и фильтр работают быстро, увеличение числа типов цен и складов может незаметно замедлить корзину и оформление заказа — эти страницы стоит тестировать отдельно [11].

Как выбрать решение под свой каталог

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

Если каталог изначально проектировался с сотнями свойств и множеством типов цен, а нагрузка растёт вместе с ассортиментом — стоит заранее считать размер фасетного индекса и рассматривать переход на инфоблоки 2.0 или Highload-блоки, не дожидаясь критической деградации.

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

Как может помочь «Пятый фактор»

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

Вывод

Каталог на 1С-Битрикс способен стабильно работать при объёмах от тысяч до сотен тысяч товаров — это подтверждают и независимые нагрузочные тесты, и практика проектов с миллионами SKU. Ключ к скорости — не отказ от платформы, а понимание того, какие именно механизмы (кеширование, фасетный индекс, структура инфоблоков) отвечают за производительность и как они ведут себя при росте данных. Начинать стоит с диагностики и настроек, переходить к структурным изменениям по мере роста каталога и рассматривать внешние поисковые движки только тогда, когда встроенные механизмы объективно исчерпали свой запас прочности.

Источники

[1] docs.1c-bitrix.ru — Композитный сайт — https://docs.1c-bitrix.ru/pages/performance/composite-site.html

[2] dev.1c-bitrix.ru — Кеширование при проектировании сайта — https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=2991

[3] maxiplace.ru — Как ускорить сайт на 1С-Битрикс: 14 шагов — https://maxiplace.ru/blog/bitrix/14-shagov-kak-uskorit-bitrix/

[4] dev.1c-bitrix.ru — Автокеширование — https://dev.1c-bitrix.ru/user_help/settings/settings/cache.php

[5] habr.com — Highload-блоки в Битрикс24 — https://habr.com/ru/companies/otus/articles/827008/

[6] itrack.ru — Модуль Highload-блоки 1С-Битрикс — https://itrack.ru/license/module/highload-bloki/

[7] sendev.ru — Работа с Highload-блоками в Битрикс D7 — https://sendev.ru/blog/1c-bitrix/rabota-s-highload-blokami-v-d7/

[8] dev.1c-bitrix.ru — Highload-блоки (курс «Разработчик Bitrix Framework») — https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&CHAPTER_ID=05745

[9] sendev.ru — CIBlockElement::GetList(): руководство и оптимизация производительности — https://sendev.ru/blog/1c-bitrix/ciblockelement-getlist-ispolzovanie-i-primery/

[10] xlogic.ru — D7 vs CIBlockElement: выбор API для работы с инфоблоками — https://xlogic.ru/blog/bitva-proizvoditelnosti-d7-vs-staryy-api-ciblockelement-kogda-chto-ispolzovat-i-pochemu/

[11] intervolga.ru — Повышаем производительность Битрикс при больших объемах данных — https://www.intervolga.ru/blog/projects/bolshie-obemy-dannykh-v-bitriks-chto-ubivaet-proizvoditelnost/

[12] helpdesk.bitrix24.ru — Технические требования (для коробочной версии) — https://helpdesk.bitrix24.ru/open/5825131/

[13] kingservers.com — Хостинг 1C-Битрикс: быстро, стабильно, надёжно — https://kingservers.com/blog/hosting-1c-bitrix-bystraya-rabota-sayta/

[14] temofeev.com — Оптимизация производительности 1С-Битрикс — https://temofeev.com/info/articles/optimizatsiya-proizvoditelnosti-1c-bitrix/

[15] blagoit.com — Умный фильтр в 1С-Битрикс: полное руководство — https://blagoit.com/blog/blog-o-razrabotki-saytov/umnyy-filtr-v-1s-bitriks-polnoe-rukovodstvo/

[16] semantica-media.ru — Умный SEO-фильтр в Битриксе — https://semantica-media.ru/blog/umnyj-filtr-bitriks-kak-ego-dobavit-i-pravilno-nastroit.html

[17] yavorsky.ru — Как ускорить сайт на 1С-Битрикс — https://yavorsky.ru/stati/kak-uskorit-sayt-na-1s-bitriks/

[18] aspro.ru — Ускорение сайта на 1С-Битрикс: полный гайд — https://aspro.ru/materials/how-speed-up-bitrix-site/

[19] qna.habr.com — обсуждение анти-паттерна CIBlockElement::GetByID в цикле — https://qna.habr.com/user/Danbka/comments?page=4

Нужна помощь по этой задаче?
На странице услуги «Базовая оптимизация сервера и базы под Битрикс» указаны состав работ, результат и фиксированная цена.