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