defer и async изменяют когда внешний <script> загружается и выполняется относительно парсирования HTML. Оба позволяют скрипту загружаться параллельно без блокирования парсера — различие в времени выполнения.
html
defer и async изменяют когда внешний <script> загружается и выполняется относительно парсирования HTML. Оба позволяют скрипту загружаться параллельно без блокирования парсера — различие в времени выполнения.
Normal: parse──stop──[download+exec]──parse──────── (slowest)
async: parse──────────────────exec──parse──────── (runs whenever it arrives)
defer: parse───────────────────────────parse──exec (after parsing, before DOMContentLoaded)
async | defer | |
|---|---|---|
| Загрузка | параллельно | параллельно |
| Выполняется | сразу после загрузки | после полного парсирования HTML |
| Порядок сохранён? | Нет (кто загрузится первым) | Да (порядок документа) |
| Блокирует парсер? | только кратко во время exec | никогда |
defer — для скриптов, которые изменяют DOM или зависят друг от друга/порядка (код приложения). Выполняются после создания DOM, по порядку, прямо перед DOMContentLoaded.async — для независимых сторонних скриптов, которые не зависят от DOM или других скриптов (аналитика, реклама). Порядок не имеет значения, запускайте их как можно скорее.<script src="analytics.js" async></script> <!-- independent → async -->
<script src="app.js" defer></script> <!-- app logic, ordered → defer -->
Примечание: оба применяются только к внешним скриптам (src); они игнорируются во встроенных скриптах. ES модули (type="module") откладываются по умолчанию.
Использование defer/async предотвращает блокирование парсирования HTML скриптами, что напрямую улучшает производительность загрузки и First Contentful Paint.
Выбор правильного (defer для упорядоченного кода приложения, зависящего от DOM, async для сторонних скриптов «установил и забыл») избегает как медленной загрузки, так и ошибок зависимости от порядка.