Настройка асинхронной загрузки JS для 1С-Битрикс
Самый частый симптом: Lighthouse показывает «Eliminate render-blocking resources», в списке — jQuery, Swiper, компонентные скрипты Битрикс. Браузер парсит HTML, встречает <script src="..."> без атрибутов и останавливает рендер до скачивания и выполнения файла. На типовом Битрикс-сайте таких блокирующих скриптов набирается 5–10.
Механизм управления JS в Битриксе
Битрикс регистрирует скрипты через CMain::AddHeadScript() и Asset::getInstance()->addJs(). Метод ShowHead() выводит их в <head> без defer/async. Компоненты добавляют скрипты через $APPLICATION->AddHeadScript() — то же самое. Переопределить поведение можно только на уровне шаблона или через постобработку буфера.
Добавление defer/async через шаблон
Самый безопасный способ — использовать событие 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"> — браузер скачивает файл с высоким приоритетом, но выполнение происходит в порядке, контролируемом разработчиком.
Кейс: сайт туристической компании
Сайт на Битрикс «Старт» с поисковой формой на главной. TBT (Total Blocking Time) в Lighthouse — 1 840 мс. Причина: 12 скриптов в <head>, включая Swiper 8.1 (120 КБ), Fancybox (80 КБ), карта Яндекс (асинхронная API, но инициализация блокирующая).
После добавления defer через OnEndBufferContent и переноса карты на отложенную инициализацию через IntersectionObserver:
- TBT: 1 840 мс → 240 мс
- TTI (Time to Interactive): 6,1 с → 2,8 с
- Lighthouse Performance score: 34 → 78
Работы — 1 день.







