defer & asyncHoe en wanneer een script wordt uitgevoerd, heeft impact op laadsnelheid en of je code de DOM al kan
gebruiken.
In dit stuk leggen we kort uit wat parsen is en hoe defer en async
werken.
Parsen = de browser leest je HTML-tekst en zet die om naar een DOM-boom (Document Object Model). CSS wordt omgezet naar de CSSOM. Daarna combineert de browser DOM + CSSOM om te renderen (layout & paint).
HTML → DOM (nodes: <header>, <nav>, <main>, …)
CSS → CSSOM (regels, selectors, uiteindelijke waarden)
DOM + CSSOM → Render tree → Layout → Paint
defer voorkom je dat.
defer: downloadt parallel, blokkeert niet, voert pas uit als de HTML
klaar is (vlak vóór DOMContentLoaded).async: downloadt parallel en voert meteen uit zodra klaar (volgorde
onvoorspelbaar).defer — “download nu, voer later uit” ✅<!-- In <head>: vroeg downloaden, laat uitvoeren -->
<script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="/assets/js/main.js"></script>
Tijdlijn:
HTML parsen ───────────────┐ (DOM klaar)
defer scripts downloaden ──┘──► voer defer-scripts uit ─► DOMContentLoaded
async — “download nu, voer ASAP uit”DOMContentLoaded wacht niet op async scripts.<script async src="/js/analytics.js"></script>
| Blokkeert parser? | Volgorde gegarandeerd? | Wanneer uitgevoerd? | Gebruik voor… | |
|---|---|---|---|---|
| zonder attribuut | Ja | Ja | Direct bij encounter | Uitzonderlijk (kleine inline scripts) |
defer |
Nee | Ja | Na parsen, vóór DOMContentLoaded |
App-scripts, frameworks, Bootstrap |
async |
Nee | Nee | Zodra download klaar is | Onafhankelijke scripts |
<head> met defer.<body>? Dan is defer niet strikt nodig (DOM is dan al
klaar).async alleen als het script nergens van afhangt.type="module" scripts gedragen zich van nature “defer-achtig”.Plak dit in je project en bekijk de console-volgorde:
<!-- in <head> -->
<script defer src="/assets/js/a.js"></script>
<script defer src="/assets/js/b.js"></script>
// a.js
console.log('A start');
document.addEventListener('DOMContentLoaded', () => console.log('A DOM ready'));
console.log('A end');
// b.js
console.log('B start');
document.addEventListener('DOMContentLoaded', () => console.log('B DOM ready'));
console.log('B end');
Verwacht:
A start → A end → B start → B end → A DOM ready → B DOM ready
defer: werkt niet; defer geldt alleen voor externe
scripts.async = “asap run”, defer = “later run (na HTML)”.