Настройка асинхронной загрузки JS для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка асинхронной загрузки JS для 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка асинхронной загрузки 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 день.