Коротка відповідь
juniorasync — це атрибут, який дозволяє браузеру завантажувати скрипт паралельно з парсингом HTML, а defer гарантує, що виконання скрипта відбудеться після завершення парсингу. При async скрипт виконується, коли він готовий; при defer – після повного парсингу DOM. Тому async підходить для незалежних скриптів, а defer – коли потрібна послідовність виконання після побудови DOM.
Повне пояснення
Що це і навіщо
- async: завантажує скрипт асинхронно, не блокуючи парсинг HTML. Скрипт виконується одразу після завантаження, незалежно від того, чи завершено парсинг.
- defer: також завантажує скрипт асинхронно, але гарантує виконання лише після завершення парсингу всього документа. Скрипти з defer виконуються у тому порядку, в якому вони оголошені.
Ключові принципи/терміни
- парсинг DOM – процес побудови дерева елементів.
- завантаження (fetch) – отримання файлу скрипта.
- виконання – запуск коду в контексті сторінки.
Як це працює
- Браузер читає HTML, натрапляючи на тег
<script>. - Якщо атрибут
asyncприсутній, браузер відразу ініціює завантаження скрипта в окремому потоці, не зупиняючи парсинг. - Якщо атрибут
deferприсутній, браузер також завантажує скрипт паралельно, але ставить його у чергу виконання. - Після завершення парсингу DOM браузер виконує всі скрипти з
deferу порядку їх появи. - Скрипт з
asyncвиконується, коли завантаження завершено, що може статися в будь-який момент.
Практика і реалізація
<script src="analytics.js" async></script>
<script src="app.js" defer></script>
analytics.jsне залежить від DOM, тому його можна виконати в будь‑який момент.app.jsпотребує, щоб DOM був готовий, тому використовуєтьсяdefer.
Тестування
- Для перевірки порядку виконання можна використати
console.logу скриптах і спостерігати порядок в консолі. - У Jest можна мокнути
document.createElementі перевірити, що скрипти додаються з правильними атрибутами.
Особливості в контексті веб‑розробки
asyncпідходить для сторонніх бібліотек (наприклад, Google Analytics), де порядок виконання не критичний.deferідеально для власних скриптів, що маніпулюють DOM або залежать один від одного.
Оптимізація
- Використання
deferз усіма внутрішніми скриптами мінімізує блокування рендеру. asyncзменшує час до першого виконання, але може викликати race conditions.
Часті помилки
- Використання
asyncдля скриптів, що модифікують DOM → помилки «document not ready». - Змішування
asyncіdeferу одному скрипті → непередбачуваний порядок. - Не врахування порядку
defer→ залежності між скриптами порушуються. - Додавання
asyncдо бібліотек, що очікують глобальних змінних → непередбачувані результати. - Використання
deferу старих браузерах (IE < 10) → не підтримується. - Додавання
asyncдо скриптів, що мають внутрішніimport→ синтаксичні помилки. - Неочікуване виконання
asyncскрипта перед завантаженням CSS → зміни стилів можуть бути не застосовані. - Підключення великого скрипта з
async→ блокування CPU, що впливає на інші ресурси.
Cheatsheet
- async: швидке завантаження, виконання коли готово, незалежно від DOM.
- defer: завантаження паралельно, виконання після парсингу DOM, у порядку оголошень.
- script без атрибутів: синхронне завантаження і виконання, блокує парсинг.
Follow‑up питання
- Які сценарії краще підходять для
async? - Як впливають
asyncіdeferна SEO та швидкість завантаження сторінки? - Чи можна комбінувати
asyncіdeferу одному скрипті, і що це означає?