Що робить defer у <script>?
Визначення
defer- це атрибут тега<script>, який каже браузеру:"Завантаж цей скрипт паралельно з HTML, але виконай його тільки після того, як весь HTML-документ буде завантажено і розібрано (DOMContentLoaded)."
1. Звичайна поведінка без defer
<script src="app.js"></script>Що відбувається:
- Браузер починає завантажувати HTML.
- Зустрічає
<script>. - Зупиняє парсинг HTML, щоб:
- завантажити
app.js, - виконати його.
- Тільки потім продовжує завантажувати сторінку.
У результаті сторінка завантажується повільніше, тому що JS блокує HTML.
2. Що робить defer
<script src="app.js" defer></script>Тепер браузер:
- Починає завантажувати HTML і JS паралельно.
- Не блокує парсинг HTML.
- Виконує
app.jsтільки після того, як DOM повністю побудований, але до подіїDOMContentLoaded.
Тобто:
- HTML парситься ->
- скрипт завантажується у фоні ->
- DOM готовий ->
- скрипт виконується ->
- -> спрацьовує
DOMContentLoaded.
3. Приклад різниці
<!-- Без defer -->
<script src="slow.js"></script>
<p>Привіт!</p>
<!-- З defer -->
<script src="slow.js" defer></script>
<p>Привіт!</p>З defer текст "Привіт!" з'явиться одразу,
поки скрипт ще завантажується.
Без defer сторінка зависне, поки не завантажиться slow.js.
4. Коли скриптів декілька
<script src="a.js" defer></script>
<script src="b.js" defer></script>Скрипти з defer:
- завантажуються паралельно,
- але виконуються у порядку появи в HTML.
Це головна відмінність від async, де порядок не гарантується (див. нижче).
5. Відмінність defer від async
| Атрибут | Коли завантажується | Коли виконується | Гарантований порядок | Типовий сценарій |
|---|---|---|---|---|
| (без атрибута) | Одразу при зустрічі | Одразу (блокує HTML) | Так | Старий JS у <head> |
| async | Паралельно з HTML | Одразу після завантаження (не чекає DOM) | Ні | Аналітика, реклама, віджети |
| defer | Паралельно з HTML | Після побудови DOM | Так | Основні скрипти застосунку |
6. Сумісність
Працює у всіх сучасних браузерах.
Якщо використовувати в <head>, це найправильніший спосіб підключати JS:
<head>
<script src="main.js" defer></script>
</head>Браузер не блокує завантаження сторінки і гарантує, що твій код виконається, коли DOM уже готовий.
7. Вплив на DOMContentLoaded
DOMContentLoaded спрацьовує після виконання всіх defer-скриптів.
Тобто можна бути впевненим, що на момент цієї події твої скрипти вже відпрацювали.
Підсумок
| Властивість | Без атрибута | async | defer |
|---|---|---|---|
| Завантажує скрипт | Одразу (блокує HTML) | Паралельно | Паралельно |
| Виконує скрипт | Одразу після завантаження | Одразу після завантаження | Після розбору HTML |
| Порядок виконання | По порядку | Довільний | По порядку |
| Блокує HTML | Так | Ні | Ні |
| Чекає DOM | Ні | Ні | Так |
Запам'ятай просто:
defer- "завантаж одразу, виконай потім".- Використовуй його для основних JS-файлів, щоб сторінка завантажувалася швидко і без "білих екранів".
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.