Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чим "defer" відрізняється від "async" у <script>?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Обидва атрибути, **`defer`** і **`async`**, завантажують скрипт асинхронно, не блокуючи парсинг HTML, але відрізняються моментом виконання: `defer` виконує скрипт лише після повного парсингу HTML і зберігає порядок скриптів, а `async` виконує його одразу після завантаження, у непередбачуваному порядку. **Ключове:** `defer` підходить для основної логіки сайту, що залежить від DOM, а `async` - для незалежних скриптів на кшталт аналітики чи реклами.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Проблема, яку вирішують `defer` і `async` Коли браузер зустрічає тег: ```javascript <script src="script.js"></script> ``` за умовчанням він: 1. **Зупиняє парсинг HTML**, 2. Завантажує `script.js`, 3. Виконує його, 4. Тільки потім **продовжує будувати DOM**. Це блокує рендер сторінки -> користувач бачить "порожній екран", поки JS не завантажиться. Тому з'явилися атрибути `defer` і `async`, щоб **не блокувати HTML-парсинг**. --- ## `defer` ```javascript <script src="script.js" defer></script> ``` **Як це працює:** 1. Скрипт **завантажується паралельно** з HTML (асинхронно). 2. Але **виконується тільки після повного парсингу HTML** - тобто **коли DOM готовий**, але **до події** `DOMContentLoaded`. 3. Скрипти з `defer` виконуються **у порядку, у якому вони вказані в HTML**. Чудово підходить для "основних" скриптів застосунку (наприклад, `main.js`, `vendor.js`). Приклад: ```javascript <script src="a.js" defer></script> <script src="b.js" defer></script> ``` Спочатку завантажаться **обидва паралельно**, але **виконаються строго по порядку:** `a.js` **->** `b.js` після побудови DOM. --- ## `async` ```javascript <script src="script.js" async></script> ``` **Як це працює:** 1. Скрипт **завантажується паралельно** з HTML (як `defer`), 2. Але **виконується одразу після завантаження**, навіть якщо HTML ще не допарсено. 3. Скрипти з `async` виконуються **у непередбачуваному порядку**, - залежно від того, який швидше завантажиться. Підходить для **незалежних** скриптів (наприклад, аналітика, реклама, метрики). Приклад: ```javascript <script src="a.js" async></script> <script src="b.js" async></script> ``` `b.js` може виконатися **раніше**, якщо завантажився швидше, навіть якщо в HTML він був нижче. --- ## Порівняння `defer` і `async` | Властивість | `defer` | `async` | |---|---|---| | Завантаження скрипта | Асинхронно (паралельно з HTML) | Асинхронно | | Виконання | Після повного парсингу HTML | Одразу після завантаження | | Порядок виконання | Зберігається | Не гарантується | | Блокує HTML-парсинг | Ні | Ні | | Подія `DOMContentLoaded` | Чекає виконання всіх `defer`-скриптів | Не чекає | | Типові сценарії | Основна логіка сайту | Зовнішні трекери, реклама | --- ## Приклад візуально ```javascript <!-- HTML парситься... --> <script src="main.js" defer></script> <script src="analytics.js" async></script> ``` Процес: | Етап | Що відбувається | |---|---| | 1 | Браузер починає парсити HTML | | 2 | Одночасно завантажує обидва скрипти | | 3 | `analytics.js` (async) завантажується швидше -> виконується **одразу** | | 4 | HTML парситься до кінця | | 5 | Потім виконується `main.js` (defer) | | 6 | Потім спрацьовує `DOMContentLoaded` | --- ## Висновки | Атрибут | Коли використовувати | |---|---| | `defer` | Для основного JS-коду, який залежить від DOM (наприклад, ініціалізація інтерфейсу) | | `async` | Для незалежних скриптів (аналітика, метрики, реклама) | | **Без атрибутів** | Тільки якщо потрібно заблокувати парсинг HTML (рідко потрібно) | --- ## Порада Якщо ти використовуєш **сучасний bundler** (Next.js, Vite, Webpack) - він сам ставить `defer` для `<script>` у `head`, тому в сучасних застосунках **це вже best practice за умовчанням**.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.