Сначала зависимости, затем атрибут

Как безопасно отложить JavaScript

Для независимого кода подходит async, для упорядоченной цепочки — defer, а тяжёлую необязательную функцию можно загружать по событию. Выбор делается для каждого скрипта после проверки назначения.

Схема выбора между defer, async и загрузкой JavaScript по событию
Один атрибут для всех тегов может нарушить порядок инициализации.

Самый безопасный путь

Сообщение разработчику или поддержке

«Найдите синхронные внешние JavaScript в head, составьте карту зависимостей и предложите defer, async или загрузку по событию для каждого файла. Сохраните резервную копию, не откладывайте критический код вслепую и проверьте меню, формы, корзину, оплату, аналитику, Console и waterfall на desktop/mobile».

Перед изменением сохраните шаблон и конфигурацию сборки, включите версионирование файлов и запишите рабочие сценарии. Меняйте по одной группе, чтобы источник сбоя оставался понятен.

Пошаговая настройка

  1. В DevTools → Network отфильтруйте JS и найдите синхронные внешние теги в исходном HTML.
  2. Для каждого файла укажите владельца, назначение, зависимости и элементы DOM, которые он ожидает.
  3. Оставьте синхронным только действительно критичный код, необходимость которого подтверждена тестом.
  4. Для цепочки библиотека → плагин → инициализация добавьте defer всем внешним участникам в нужном порядке.
  5. Независимую аналитику или интеграцию используйте с async только если порядок не важен.
  6. Необязательный виджет ниже первого экрана загружайте при приближении блока или осознанном взаимодействии, предусмотрев видимую кнопку и состояние ошибки.
  7. Очистите кеш, повторите waterfall и функциональные сценарии на desktop/mobile с медленной сетью.

Техническая памятка

Упорядоченные зависимости

<script defer src="/js/library.js"></script>
<script defer src="/js/app.js"></script>

defer сохраняет порядок внешних классических скриптов и запускает их после разбора HTML.

Независимый скрипт

<script async src="https://vendor.example/analytics.js"></script>

async выполняется после загрузки и не гарантирует порядок относительно соседних тегов.

У type="module" по умолчанию отложенное выполнение; для старых браузеров и nomodule проверяйте выбранную стратегию проекта. Атрибут defer не действует на классический inline-скрипт без src.

Риски, откат и проверка

Типичные сбои после изменения порядка
СимптомПричинаДействие
… is not definedПотребитель запустился раньше зависимостиВернуть порядок и использовать defer для цепочки
Кнопка реагирует только со второго разаОбработчик добавлен слишком поздноИнициализировать лёгкий обработчик раньше
Потеря событий аналитикиОчередь событий не создана до загрузкиВернуть рекомендованный bootstrap поставщика
Улучшился render, ухудшился INPТяжёлое выполнение сдвинулось к взаимодействиюРазделить задачу или загрузить заранее в простой

Для отката восстановите прежние теги и сборку, очистите кеш и повторите критические действия. После правки выполните независимую проверку. Минификация, удаление кода и исправление логики оцениваются отдельно.