8 lines
17 KiB
JSON
8 lines
17 KiB
JSON
{
|
||
"index": 186,
|
||
"slug": "editorial-2022-11-practice-bitrix-performance",
|
||
"title": "Производительность Bitrix-страницы: как найти узкое место без оптимизации наугад",
|
||
"excerpt": "Разделяем маршрут, компонент, кеш и шаблон, проверяем зависимость результата и выбираем одно обратимое действие вместо отключения кеша вслепую.",
|
||
"contentHtml": "<p>Страница каталога открывается медленно, а в разговоре звучит только одно объяснение: «тормозит Bitrix». Такой диагноз ничего не проверяет. Он не показывает, какой URL воспроизводит симптом, какой компонент формирует блок, где срабатывает кеш и какой шаблон отдаёт HTML. Цена ошибки — лишние запросы к базе, отключённый кеш, переписанный шаблон и тот же медленный экран. После нескольких изменений команда уже не знает, что именно помогло или что безопасно вернуть.</p>\n<p>Начинайте с наблюдаемого факта. Запишите маршрут, вариант входа, компонент, шаблон и условие, при котором HTML меняется. Если часть сведений неизвестна, оставьте её неизвестной. Это лучше, чем заменить пробел догадкой. Производительность страницы нельзя объяснить одним слоем: запрос, компонент, кеш и рендеринг связаны, но проверяются отдельно.</p>\n<h2>Тезис: сначала отделите границы, потом меняйте код</h2>\n<p>Одна правка должна отвечать на один вопрос. Например: «входит ли группа пользователя в зависимость кеша этого компонента?» Это проверяемый вопрос. «Почему Bitrix медленный?» — нет. Пока вопрос не ограничен, нельзя выбрать ни инструмент, ни безопасное действие.</p>\n<p>Разделите страницу на четыре границы. Маршрут задаёт вход. Компонент принимает параметры и получает данные. Кеш решает, нужно ли снова выполнять вычисление и сохраняет ли результат. Шаблон превращает результат компонента в HTML. Большой HTML не доказывает медленный SQL. Наличие кеша в настройках не доказывает cache hit на нужном запросе. Видимый шаблон не доказывает, что он стал причиной задержки.</p>\n<div class=\"table-scroll\"><table><caption>Что проверять до правки страницы</caption><thead><tr><th scope=\"col\">Симптом</th><th scope=\"col\">Возможная причина</th><th scope=\"col\">Проверка</th><th scope=\"col\">Действие</th></tr></thead><tbody><tr><td>Один и тот же каталог долго формирует ответ</td><td>Дорогая ветка компонента или промах кеша</td><td>Повторить тот же URL и записать компонент, параметры и режим кеша</td><td>Получить один разрешённый серверный или прикладной артефакт, не меняя TTL</td></tr><tr><td>Разные пользователи видят разный HTML</td><td>Группа, право или сегмент не вошли в ключ</td><td>Сверить все условия output с <code>additionalCacheID</code> и параметрами</td><td>Добавить зависимость или остановить изменение до уточнения контракта</td></tr><tr><td>После очистки кеша первый запрос снова тяжёлый</td><td>Очистка убрала результат, но не устранила стоимость построения</td><td>Сравнить холодный и повторный вход на одном маршруте</td><td>Искать стоимость формирования, а не считать очистку исправлением</td></tr><tr><td>Кеш работает, но HTML всё ещё избыточен</td><td>В результат попадают лишние данные</td><td>Проверить, нужен ли компоненту полный <code>arResult</code> и вызван ли <code>SetResultCacheKeys</code></td><td>Сократить сохраняемые данные только после проверки шаблона</td></tr><tr><td>После изменения исчезают данные для части посетителей</td><td>Нарушена зависимость результата или изменён шаблон</td><td>Повторить исходный вход и сравнить HTML и условия доступа</td><td>Вернуть один diff и разобрать недостающий input</td></tr></tbody></table></div>\n<h2>Как устроено кеширование компонента</h2>\n<p>Встроенное кеширование Bitrix начинается с <code>StartResultCache</code>. При действующем кеше метод возвращает <code>false</code> и отдаёт сохранённый результат. При недействующем кеше он возвращает <code>true</code>, после чего компонент получает данные и подключает шаблон. По документации базовая зависимость включает сайт, имя компонента, имя шаблона и входные параметры <code>$arParams</code>. Дополнительное условие передают отдельно.</p>\n<p>Это контракт, а не измерение скорости. Он говорит, от чего должен зависеть результат, но не сообщает, сколько заняло выполнение запроса и был ли конкретный запрос cache hit. Если HTML зависит от группы пользователя, права доступа, языка или другого значения, такого условия нельзя оставлять только в PHP-ветке. Оно должно участвовать в зависимости результата. Иначе один сохранённый HTML может попасть к другому варианту посетителя.</p>\n<p><code>SetResultCacheKeys</code> решает другую задачу. Метод задаёт поля <code>$arResult</code>, которые нужно сохранить для использования после чтения кеша. Если его не вызвать внутри участка с <code>StartResultCache</code>, ядро может сериализовать весь результат. Лишние данные увеличивают размер кеша, но сам факт большого кеша ещё не доказывает, что он является главным узким местом страницы.</p>\n<figure><img src=\"/assets/editorial/2022/bitrix-performance-2022-request-contract.svg\" alt=\"Схема разбора производительности Bitrix-страницы: маршрут передаёт вход компоненту, компонент проверяет кеш и формирует HTML через шаблон; на каждой границе фиксируется отдельный факт.\" loading=\"lazy\" /><figcaption>Один запрос проходит несколько границ. Проверяйте их по отдельности: объявленная зависимость кеша не заменяет измерение времени ответа.</figcaption></figure>\n<h2>Учебный пример компонента</h2>\n<p>Ниже показана сокращённая схема, а не готовый код для конкретного проекта. Число инфоблока, параметры и поле группы вы должны заменить фактическими значениями. Пример нужен, чтобы увидеть место проверки зависимости и отрицательный путь. Он не сообщает production-результаты и не измеряет время.</p>\n<pre><code>if ($this->StartResultCache(false, [$USER->GetGroups(), $arParams['LANGUAGE_ID']])) {\n $this->arResult = loadCatalogItems($arParams['IBLOCK_ID']);\n\n if (!$this->arResult) {\n $this->AbortResultCache();\n return;\n }\n\n $this->SetResultCacheKeys(['SECTION_ID', 'ITEM_COUNT']);\n $this->IncludeComponentTemplate();\n}</code></pre>\n<p>В этом учебном варианте группа пользователя и язык входят в дополнительную зависимость, потому что они могут менять результат. Пустой результат останавливает кеширование через <code>AbortResultCache</code>: иначе отрицательный или неполный ответ может сохраниться как обычный. Нельзя переносить этот список в проект без проверки. Если HTML зависит от другой переменной, её нужно назвать и проверить отдельно.</p>\n<p>Обратный путь так же важен, как успешный. Если вы не знаете, меняет ли условие HTML, не увеличивайте срок кеша и не выключайте кеш полностью. Сначала найдите владельца компонента, прочитайте параметры и определите output contract. Если разрешённого артефакта нет, корректное действие — остановить оптимизацию и зафиксировать недостающий факт.</p>\n<h2>Порядок диагностики</h2>\n<ol><li><strong>Зафиксируйте симптом.</strong> Укажите один URL, вариант запроса и наблюдаемое поведение. Не добавляйте выдуманные миллисекунды, SQL или cache hit-rate.</li><li><strong>Назовите границу.</strong> Найдите подключаемый компонент, его шаблон и параметры. Отдельно запишите условия, которые могут менять HTML или доступ к данным.</li><li><strong>Сверьте контракт кеша.</strong> Проверьте базовые входы и дополнительные зависимости <code>StartResultCache</code>. Не называйте кеш рабочим только потому, что в параметрах стоит ненулевой <code>CACHE_TIME</code>.</li><li><strong>Выберите один артефакт.</strong> Используйте доступный в проекте лог, профиль, трассировку или замер. Он должен различать две гипотезы: например, промах кеша и дорогую подготовку данных.</li><li><strong>Сделайте один узкий diff.</strong> Меняйте только один параметр, зависимость или шаблон. До изменения запишите, что вернуть, если результат не подтверждён.</li><li><strong>Повторите тот же вход.</strong> Сравните прежний и новый артефакт на том же URL, варианте пользователя и наборе данных. Если вход изменился, это новый эксперимент.</li></ol>\n<h2>Быстрые исправления, которые скрывают причину</h2>\n<p>Очистка всего кеша меняет состояние системы, но не объясняет стоимость формирования. После очистки первый запрос закономерно может быть тяжёлым. Выключение кеша убирает один путь и добавляет нагрузку на базу и PHP. Это не диагностика. Увеличение <code>CACHE_TIME</code> может уменьшить число построений, но закрепит неверный HTML, если ключ неполон.</p>\n<p>Переписывать шаблон только потому, что он виден в каталоге файлов, тоже рискованно. Шаблон отвечает за вывод, но не обязан отвечать за дорогой запрос. Сначала проверьте, что компонент уже получил данные и сколько данных он сохраняет. И наоборот: уменьшение <code>arResult</code> не исправит медленный SQL, если запрос выполняется до формирования результата.</p>\n<p>Не смешивайте в одной правке кеш, SQL, PHP и браузер. Иначе положительный результат нельзя связать с одним изменением. Если гипотеза не подтверждается, верните именно этот diff и повторите исходный вход. Откат всей страницы или массовая очистка кеша уничтожают полезный контекст.</p>\n<h2>Ограничения и критерий готовности</h2>\n<p>Документация Bitrix описывает API кеширования, но не знает самописный компонент, версию PHP, структуру базы, настройки окружения и реальные условия пользователя. Учебный код не заменяет профиль. Названия <code>IBLOCK_ID</code>, <code>LANGUAGE_ID</code> и группы в примере не являются данными конкретного сайта. Статья также не утверждает, что любая Bitrix-страница станет быстрее после добавления кеша.</p>\n<p>Диагностика готова, когда выполнены все четыре условия: выбран один воспроизводимый маршрут; назван компонент и его шаблон; перечислены входы, которые меняют результат и кеш; сохранён артефакт до и после одного обратимого изменения. Действие считается успешным только при повторном замере того же входа и при отсутствии нового нарушения содержимого или доступа. Если хотя бы одного условия нет, готов не результат, а следующий вопрос.</p>\n<h2>Проверяемые источники</h2><ul><li><a href=\"https://dev.1c-bitrix.ru/api_help/main/reference/cbitrixcomponent/startresultcache.php\" target=\"_blank\" rel=\"noopener noreferrer\">1С-Битрикс: CBitrixComponent::StartResultCache</a> — описывает возврат <code>true</code>/<code>false</code>, базовые зависимости кеша и параметр дополнительных условий.</li><li><a href=\"https://dev.1c-bitrix.ru/api_help/main/reference/cbitrixcomponent/setresultcachekeys.php\" target=\"_blank\" rel=\"noopener noreferrer\">1С-Битрикс: CBitrixComponent::SetResultCacheKeys</a> — описывает выбор полей <code>$arResult</code>, сохраняемых при встроенном кешировании компонентов.</li><li><a href=\"https://dev.1c-bitrix.ru/api_help/main/reference/cbitrixcomponent/abortresultcache.php\" target=\"_blank\" rel=\"noopener noreferrer\">1С-Битрикс: CBitrixComponent::AbortResultCache</a> — описывает остановку кеширования, когда результат нельзя сохранять.</li></ul>"
|
||
}
|