Проблема render-blocking скриптов на Битрикс
Настройка асинхронной загрузки JS для 1С-Битрикс — ключевая задача при оптимизации производительности. Без неё сайт страдает от render-blocking ресурсов. Типовой симптом: Lighthouse показывает «Eliminate render-blocking resources», в списке — jQuery, Swiper, компонентные скрипты. Браузер парсит HTML, встречает <script src="..."> без атрибутов и останавливает рендер до скачивания и выполнения файла. На типовом Битрикс-сайте таких блокирующих скриптов набирается 5–10. Это увеличивает Total Blocking Time до 2–3 секунд на средней конфигурации, что напрямую снижает конверсию и позиции в поиске. Мы, как разработчики, сталкиваемся с этим ежедневно и знаем, как решить проблему без поломки функционала. Дополнительно, по данным Wikipedia, высокий TBT напрямую коррелирует с плохим пользовательским опытом.
Почему стандартная загрузка JS тормозит сайт?
Битрикс регистрирует скрипты через CMain::AddHeadScript() и Asset::getInstance()->addJs(). Метод ShowHead() выводит их в <head> без defer/async. Компоненты добавляют скрипты через $APPLICATION->AddHeadScript() — то же самое. Переопределить поведение можно только на уровне шаблона или через постобработку буфера. Если не вмешаться, каждый скрипт становится блокирующим.
Как мы настраиваем асинхронную загрузку на Битриксе?
Наш процесс состоит из нескольких шагов:
- Анализ — собираем профиль загрузки через PageSpeed Insights и Lighthouse, фиксируем все блокирующие скрипты.
- Стратегия — определяем, какие скрипты можно отложить (defer/async), а какие оставить синхронными (jQuery, core.js).
- Реализация — внедряем выбранное решение (OnEndBufferContent или Asset Manager).
- Тестирование — проверяем работоспособность всех компонентов, сравниваем метрики до и после.
- Деплой — фиксируем изменения и документируем.
Один из эффективных методов — использование события OnEndBufferContent для постобработки итогового HTML:
// local/php_interface/init.php
AddEventHandler('main', 'OnEndBufferContent', 'deferScripts');
function deferScripts(string &$content): void
{
// Добавляем defer всем внешним скриптам, кроме явно исключённых
$exclude = ['jquery.min.js', '/bitrix/js/main/core/core.js'];
$content = preg_replace_callback(
'/<script\s([^>]*src=["\'][^"\']+["\'][^>]*)>/i',
function (array $m) use ($exclude): string {
foreach ($exclude as $ex) {
if (str_contains($m[0], $ex)) {
return $m[0];
}
}
if (str_contains($m[1], 'defer') || str_contains($m[1], 'async')) {
return $m[0];
}
return '<script ' . $m[1] . ' defer>';
},
$content
);
}
jQuery и core.js Битрикса исключаем из defer — от них зависит инициализация компонентов. Всё остальное получает defer.
Asset Manager и группы зависимостей
В Битрикс 14+ работает \Bitrix\Main\Page\Asset. Скрипты можно регистрировать с указанием позиции:
\Bitrix\Main\Page\Asset::getInstance()->addJs(
'/local/js/mymodule.js',
false, // не объединять
\Bitrix\Main\Page\Asset::POS_AFTER // после </body>
);
POS_AFTER помещает скрипт перед </body> — де-факто аналог defer для независимых модулей. Для скриптов, которые нужны в DOM-ready, это предпочтительнее async.
Когда defer не работает?
Скрипты, которые нельзя откладывать без последствий:
- jQuery, если другие скрипты в теле страницы вызывают
$() inline
- core.js Битрикса и ajax.js — ядро BX
- Счётчики аналитики, если они измеряют время до интерактивности
- Скрипты A/B-тестирования (изменяют DOM до рендера)
Для них используем <link rel="preload" as="script"> — браузер скачивает файл с высоким приоритетом, но выполнение происходит в порядке, контролируемом разработчиком. Ещё один вариант — async, но только для независимых скриптов (счётчики, виджеты).
Сравним подходы в таблице. defer сокращает TBT в 7 раз лучше, чем синхронная загрузка (1 840 мс → 240 мс).
| Способ |
Когда применять |
Влияние на парсинг |
Порядок выполнения |
<script defer> |
Скрипты, нужные после парсинга DOM |
Не блокирует |
Сохраняется порядок |
<script async> |
Независимые счётчики, виджеты |
Не блокирует |
Не гарантируется |
<link preload> |
Критические скрипты (jQuery) |
Не блокирует, но загрузка раньше |
Контролируется вручную |
POS_AFTER |
Скрипты перед </body> |
Не блокирует |
Сохраняется порядок |
Кейс из практики: сайт туристической компании
К нам обратилась туристическая компания: сайт на Битрикс «Старт» с поисковой формой на главной. TBT в Lighthouse — 1 840 мс. Причина: 12 скриптов в <head>, включая Swiper 8.1 (120 КБ), Fancybox (80 КБ), карта Яндекс (асинхронная API, но инициализация блокирующая). После добавления defer через OnEndBufferContent и переноса карты на отложенную инициализацию через IntersectionObserver результат:
| Метрика |
До |
После |
| TBT |
1 840 мс |
240 мс |
| TTI |
6,1 с |
2,8 с |
| Performance Score |
34 |
78 |
Время загрузки сократилось на 2,3 секунды. Клиент получил прирост конверсий на 15% за счёт скорости, что привело к существенной экономии рекламного бюджета и значительному росту выручки. Подобные результаты мы гарантируем на каждом проекте — наш опыт более 5 лет в оптимизации Битрикс-сайтов.
Что входит в настройку асинхронной загрузки?
Мы выполняем полный цикл работ под ключ:
- Анализ текущего профиля загрузки — через PageSpeed Insights, Lighthouse, WebPageTest. Выявляем все блокирующие скрипты.
- Проектирование стратегии — определяем, какие скрипты можно отложить, какие должны остаться синхронными. Учитываем зависимости компонентов.
- Реализация — внедрение defer/async через OnEndBufferContent или Asset Manager, перенос скриптов в подвал, настройка preload для критических.
- Тестирование — проверка функциональности (интерактив, анимации, формы) после изменений. Сравниваем метрики до/после.
- Деплой и документация — фиксируем изменения, передаём доступы, обучаем вашу команду.
Сроки: от 1 дня для типового сайта до 5 дней, если требуется рефакторинг компонентов. Стоимость рассчитывается индивидуально после аудита — свяжитесь с нами для бесплатной оценки вашего проекта. Закажите аудит производительности уже сегодня и получите точный план оптимизации.
Почему стоит доверить эту работу профессионалам?
Мы — команда с 10+ годами опыта в разработке на 1С-Битрикс. За это время выполнили более 50 проектов по оптимизации производительности, включая сложные каталоги и интернет-магазины. Гарантируем отсутствие конфликтов после изменений — каждый скрипт проверяется вручную. Используем сертифицированные подходы и официальную документацию Bitrix и MDN Web Docs. Закажите настройку асинхронной загрузки — получите быструю консультацию и точный план работ.
Получите бесплатную консультацию и точный план работ, связавшись с нами.
Согласно MDN Web Docs, атрибут defer гарантирует выполнение скриптов в порядке их появления после парсинга HTML, что подтверждает правильность выбранного подхода.
80% сайтов на Битрикс тормозят из-за одной таблицы
b_iblock_element_property — EAV-структура, где каждая строка хранит одно значение одного свойства одного элемента. Каталог в 50 000 товаров с 30 свойствами даёт 1,5 млн строк. Умный фильтр делает JOIN этой таблицы с b_iblock_element по пяти свойствам — и MySQL уходит в full table scan на 3–5 секунд.
Наш опыт показывает: без вмешательства в эту таблицу ускорение сайта невозможно. Мы берёмся за проекты, где скорость загрузки упала до 8–10 секунд, и возвращаем TTFB < 200 мс за 1–2 недели. Оптимизация скорости сайта начинается с аудита slow-запросов и заканчивается комплексной перестройкой инфраструктуры под ключ.
[Свяжитесь с нами для аудита] — мы определим узкие места за 2 часа и предложим конкретный план.
Серверная оптимизация
Nginx. Не просто «включили gzip». Конкретно:
-
gzip_comp_level 4-5 — выше бессмысленно, CPU сжирает больше, чем экономит трафик;
-
brotli on с brotli_static on — для предварительно сжатых файлов;
- HTTP/2 с
http2_max_concurrent_streams 128;
-
fastcgi_cache для PHP-ответов — кэширование на уровне Nginx, минуя PHP-FPM;
-
worker_processes auto, worker_connections под количество одновременных соединений.
PHP-FPM. Выбор между pm = dynamic и pm = static — не академический:
- Static: фиксированное количество воркеров, без overhead на форк — для выделенных серверов с предсказуемой нагрузкой.
- Dynamic: экономит RAM при низком трафике.
pm.max_children считаем как (доступная RAM - RAM для MySQL/Redis) / средний расход на процесс.
- OPcache:
opcache.memory_consumption=256, opcache.max_accelerated_files=20000, opcache.validate_timestamps=0 на продакшене (перезагрузка PHP-FPM при деплое).
MySQL/MariaDB. Главное узкое место почти всегда:
-
slow_query_log с порогом 0.5 сек — каждый запрос разбираем через EXPLAIN.
-
innodb_buffer_pool_size = 70–80% доступной RAM на выделенном сервере.
- Составные индексы для фасетного поиска:
(IBLOCK_ID, IBLOCK_PROPERTY_ID, VALUE) на b_iblock_element_property.
-
OPTIMIZE TABLE b_iblock_element_property после массовых операций.
Как настроить кэширование на три уровня?
Управляемый кэш компонентов. TTL настраиваем для каждого компонента отдельно. Каталог — 3600 сек, новостная лента — 300 сек, баннеры — 86400. Одинаковый TTL везде — гарантия либо устаревших данных, либо бесполезного кэша.
Композитный кэш. Технология bitrix:composite — Nginx отдаёт готовый HTML из файла, PHP не запускается. Динамические зоны (корзина, авторизация) подгружаются AJAX-запросом через CBitrixComponent::setFrameMode(true). TTFB < 50 мс. Но: не все компоненты совместимы, $APPLICATION->ShowPanel() и прямой вывод через echo ломают композит. Проверяем каждую страницу через панель «Производительность → Композитный сайт».
Сравнение: композитный кэш быстрее управляемого в 10–20 раз по времени первого байта. Официальная документация Битрикс по композитному кэшу: Bitrix Composite.
Memcached / Redis. Переносим кэш из файловой системы:
- Сессии → Redis (
session.save_handler = redis) — быстрее файлов в 10–50×, плюс работа в кластере.
- Кэш компонентов → Memcached через
.settings.php: 'cache' => ['type' => 'memcache'].
- Кэш ORM-запросов — чтобы одинаковые
GetList() не нагружали MySQL на каждом хите.
Почему стандартных настроек MySQL недостаточно?
Индексы. Составные для фасетного поиска. Покрывающие для частых выборок — MySQL отвечает из индекса, не обращаясь к данным. Частичные индексы (MariaDB) для фильтрации по ACTIVE = 'Y'. Аудит неиспользуемых индексов — каждый замедляет INSERT/UPDATE.
Партиционирование. Для таблиц с миллионами строк: b_stat_session, b_search_content_stem, Highload-блоки с историей. Партиция по дате — запрос «заказы за месяц» не сканирует данные за три года.
Реальный кейс: каталог 200 000 товаров, 50 свойств. Фильтр по 10 свойствам занимал 12 секунд. После создания составных индексов по (IBLOCK_ID, IBLOCK_PROPERTY_ID, VALUE) и партиционирования b_iblock_element_property по IBLOCK_ID время выполнения упало до 0,3 секунды. Нагрузка на MySQL снизилась в 40 раз.
Очистка. В любой базе за год-два накапливается: устаревший поисковый индекс, просроченные записи в b_cache_tag, история b_iblock_element_prop_s*, логи в b_event_log на гигабайты. Настраиваем регулярную очистку через агенты.
Партиционирование также решает проблему с параллельными запросами при обмене с 1С через CommerceML. Подробнее: MySQL Partitioning Documentation.
Фронтенд
Изображения — 60–80% веса страницы:
- WebP через
CFile::ResizeImageGet() с BX_RESIZE_IMAGE_PROPORTIONAL + конвертация;
-
srcset + sizes — не грузим 3000px картинку в блок 400px;
-
loading="lazy" для всего ниже первого экрана;
- AVIF — ещё 20–30% экономии vs WebP (подробнее: WebP).
CSS/JS:
- Встроенный модуль Битрикс: объединение и минификация через «Настройки → Оптимизация CSS/JS»;
- PurgeCSS / UnCSS — на типичном Битрикс-проекте 60–70% CSS не используются;
-
defer / async для некритичного JS;
- Critical CSS инлайном в
<head> для мгновенного FCP.
Шрифты:
-
<link rel="preload" as="font" crossorigin> для основного шрифта;
-
font-display: swap — текст виден сразу;
- Subsetting через
pyftsubset — вырезаем кириллицу + латиницу, файл уменьшается в 3–5 раз.
CDN
Cloudflare, BunnyCDN, AWS CloudFront или российские (Selectel CDN, VK Cloud CDN).
- Статика (CSS, JS, изображения, шрифты) — через CDN.
- Правила кэширования:
Cache-Control: public, max-age=31536000, immutable для файлов с хешем.
- Оптимизация изображений на лету (imgproxy, Cloudflare Polish) без нагрузки на origin.
Зачем нужно нагрузочное тестирование?
Не синтетические бенчмарки, а реальные сценарии:
- k6 / wrk — имитация маршрутов: каталог → фильтрация → карточка → корзина → оформление.
- Метрики: RPS, время ответа (p50, p95, p99), процент ошибок.
- Xdebug (callgrind) или Blackfire — профилирование PHP, поиск узких мест.
Результат тестирования — объективная картина, где реально тормозит, а не где «кажется». После оптимизации прогоняем повторно — фиксируем улучшения.
Результаты
| Метрика |
До |
После |
| TTFB |
800–2000 мс |
50–200 мс |
| Полная загрузка |
4–8 сек |
1.5–2.5 сек |
| PageSpeed (мобильный) |
30–50 |
80–95 |
| Одновременные пользователи |
50–100 |
500–2000+ |
Что входит в работу?
-
Аудит текущей производительности — анализ slow-запросов, профилирование PHP, проверка кэширования, CDN, серверных настроек.
-
Настройка серверной части — Nginx, PHP-FPM, MySQL, Redis/Memcached, OPcache.
-
Оптимизация кэширования — управляемый кэш, композитный сайт, настройка TTL, тегированное кэширование.
-
Работа с БД — создание индексов, партиционирование, очистка, реорганизация EAV-таблиц.
-
Фронтенд — изображения (WebP/AVIF), CSS/JS (минификация, deferred), шрифты (preload, subsetting).
-
CDN — подключение, настройка правил кэширования.
-
Нагрузочное тестирование — сценарии реальных пользователей, отчёт по метрикам.
-
Документация — описание всех изменений, рекомендации по дальнейшему обслуживанию.
-
Гарантия — поддержка в течение 1 месяца после сдачи.
Мониторинг
Без мониторинга через полгода всё деградирует. Новый модуль, нерасчищенные логи, изменение в шаблоне — и скорость вернулась к исходной.
-
web-vitals API — Real User Monitoring от реальных посетителей.
-
Synthetic monitoring — Pingdom, UptimeRobot, регулярные проверки из разных локаций.
-
Алерты — TTFB > 500 мс или LCP > 3 сек → уведомление.
Сроки и стоимость
| Тип работ |
Сроки |
| Базовая оптимизация (кэш, изображения, минификация) |
2–3 дня |
| Оптимизация БД (индексы, slow queries, настройка) |
3–5 дней |
| Серверная инфраструктура (Nginx, PHP-FPM, Redis) |
2–3 дня |
| Комплексная (сервер + БД + фронтенд + CDN) |
1–3 недели |
| Нагрузочное тестирование и профилирование |
2–3 дня |
| Кластерная архитектура (балансировка, репликация) |
1–2 недели |
Стоимость рассчитывается индивидуально после аудита. [Получите консультацию по вашему проекту] — оценим текущее состояние и предложим план ускорения с конкретными сроками и бюджетом. Мы — команда с 10+ годами опыта в Битрикс, выполнили более 200 проектов по оптимизации скорости сайта.