defer i async zmieniają kiedy zewnętrzny <script> jest pobierany i wykonywany w stosunku do parsowania HTML. Oba pozwalają na pobieranie skryptu równolegle bez blokowania parsera — różnica polega na czasie wykonania.
html
defer i async zmieniają kiedy zewnętrzny <script> jest pobierany i wykonywany w stosunku do parsowania HTML. Oba pozwalają na pobieranie skryptu równolegle bez blokowania parsera — różnica polega na czasie wykonania.
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 | |
|---|---|---|
| Pobieranie | równolegle | równolegle |
| Wykonywanie | gdy tylko pobrane | po pełnym sparsowaniu HTML |
| Kolejność zachowana? | Nie (który skończy się pierwszy) | Tak (kolejność dokumentu) |
| Blokuje parser? | tylko krótko podczas wykonania | nigdy |
defer — dla skryptów, które dotykają DOM lub zależą od siebie/kolejności (kod aplikacji). Wykonują się po istnieniu DOM, w kolejności, tuż przed DOMContentLoaded.async — dla niezależnych skryptów innych firm, które nie zależą od DOM ani innych skryptów (analityka, reklamy). Kolejność nie ma znaczenia, uruchom je jak najszybciej.<script src="analytics.js" async></script> <!-- independent → async -->
<script src="app.js" defer></script> <!-- app logic, ordered → defer -->
Uwaga: oba mają zastosowanie tylko do zewnętrznych skryptów (src); są ignorowane na skryptach wbudowanych. Moduły ES (type="module") są domyślnie odroczone.
Używanie defer/async uniemożliwia skryptom blokowanie parsowania HTML, co bezpośrednio poprawia wydajność ładowania i First Contentful Paint.
Wybór właściwego (defer dla uporządkowanego kodu aplikacji zależnego od DOM, async dla skryptów innych firm typu fire-and-forget) unika zarówno powolnego ładowania, jak i błędów zależności od kolejności.