Профилирование PHP-кода 1С-Битрикс (Xdebug, Blackfire)
Страница грузится 4 секунды. Nginx отдаёт быстро, MySQL тоже в порядке — а PHP тратит три секунды непонятно на что. Без профилировщика это угадывание. С профилировщиком — конкретная функция, конкретная строка, конкретное время. Разбираем два инструмента, которые реально используются в проектах на Битрикс.
Xdebug: профилирование через cachegrind
Xdebug — расширение PHP, которое умеет записывать трассировку выполнения скрипта в формате cachegrind. Файл открывается в KCachegrind (Linux) или QCacheGrind (Windows/Mac).
Установка (PHP 8.x):
pecl install xdebug
# или через apt: apt-get install php8.2-xdebug
Конфигурация в php.ini или 99-xdebug.ini:
[xdebug]
zend_extension=xdebug.so
xdebug.mode=profile
xdebug.output_dir=/tmp/xdebug
xdebug.profiler_output_name=callgrind.out.%p.%r
xdebug.start_with_request=trigger
xdebug.start_with_request=trigger — профилирование запускается только при наличии GET-параметра ?XDEBUG_PROFILE=1 или cookie. Это важно: не включайте always на боевом сервере — генерация cachegrind убивает производительность.
Запрос с профилированием:
curl "https://site.ru/catalog/product/?XDEBUG_PROFILE=1" -o /dev/null
В /tmp/xdebug появится файл callgrind.out.12345.xyz. Открываете в KCachegrind — видите дерево вызовов, процент времени каждой функции.
Что искать в профиле Битрикс
Типичные узкие места, которые вылезают в cachegrind:
-
CIBlockElement::GetList()— вызывается десятки раз на одной странице без кеша. Ищите в профиле суммарное времяGetList— если больше 30% от PHP-времени, проблема в кешировании компонентов. -
CSQLWhere::GetQuery()— сложные фильтры инфоблока без индексов. -
CBitrixComponent::includeComponent()— если вложено 20+ компонентов, каждый подключает шаблоны и CSS, накапливается overhead. -
CUser::IsAuthorized()— на некоторых конфигурациях вызывается при каждом обращении к API, не кешируется между вызовами в одном запросе. -
\Bitrix\Main\ORM\Query\Query::exec()— D7-запросы сfetchAll()на больших выборках без лимита.
Blackfire: профилирование с агрегацией
Blackfire — SaaS-решение. Агент устанавливается на сервере, PHP-расширение (blackfire.so) перехватывает выполнение, данные уходят на blackfire.io, результат — интерактивный граф вызовов в браузере.
Установка агента и расширения:
# Агент
wget -O - https://packages.blackfire.io/gpg.key | apt-key add -
echo "deb http://packages.blackfire.io/debian any main" > /etc/apt/sources.list.d/blackfire.list
apt-get update && apt-get install blackfire
# PHP-расширение
apt-get install blackfire-php
# Или через PECL:
pecl install blackfire
В php.ini:
extension=blackfire.so
blackfire.agent_socket=tcp://127.0.0.1:8307
Авторизация агента:
blackfire agent:config --server-id=XXXX --server-token=YYYY
blackfire agent:start
Запуск профилирования через CLI:
blackfire run php artisan bitrix:some-command
# или через curl:
blackfire curl https://site.ru/catalog/
Через браузерное расширение Blackfire (Chrome/Firefox) — кнопка Profile прямо на странице.
Blackfire vs Xdebug: когда что использовать
| Критерий | Xdebug cachegrind | Blackfire |
|---|---|---|
| Накладные расходы при профилировании | Высокие (~10–20x замедление) | Низкие (~2x) |
| Удобство анализа | KCachegrind (десктоп) | Веб-интерфейс, граф |
| Сравнение профилей | Вручную | Встроенная функция diff |
| Профилирование CLI-скриптов | Да | Да |
| Работа с production | Не рекомендуется | Возможно (с осторожностью) |
| Стоимость | Бесплатно | Freemium |
Xdebug — на dev-сервере для глубокой диагностики. Blackfire — когда нужно сравнить «до и после» оптимизации или профилировать staging.
Практический алгоритм оптимизации
- Базовый замер. Берём страницу, запускаем профилировщик, фиксируем топ-5 функций по времени.
-
Анализ корня. Для каждой «дорогой» функции смотрим call stack — кто её вызывает и сколько раз. Часто
GetListдорог не сам по себе, а потому что вызывается 40 раз подряд. -
Кеширование. Включаем кеш на компоненте (
CACHE_TYPE=A,CACHE_TIME=3600). Или кешируем результатGetListвручную через\Bitrix\Main\Data\Cache. - Повторный замер. Профилируем ещё раз, сравниваем с baseline.
-
Оптимизация запросов. Если запрос медленный — добавляем нужные поля в
$select, убираем лишниеIBLOCK_SECTION_IDбез индекса, переписываем сGetListна D7 ORM.
Профилирование агентов и CLI
Для фоновых агентов (\Bitrix\Main\Diag\ExceptionHandler), кроновых скриптов и CLI-команд Xdebug запускается через переменную окружения:
XDEBUG_MODE=profile XDEBUG_OUTPUT_DIR=/tmp/xdebug php -d xdebug.start_with_request=yes /path/to/bitrix-script.php
Blackfire через CLI:
blackfire run php /path/to/bitrix-script.php
Сроки
| Задача | Срок |
|---|---|
| Настройка Xdebug на dev-сервере | 2–4 часа |
| Настройка Blackfire (агент + расширение) | 4–6 часов |
| Профилирование одной страницы + отчёт | 2–4 часа |
| Профилирование + оптимизация 3–5 узких мест | 2–5 дней |
Профилирование без последующей оптимизации — бессмысленно. Мы не просто снимаем профиль и отдаём отчёт — мы исправляем найденные проблемы и замеряем итог.







