⏱️ Leestijd: ca. 3 min.

Scripts laden — parser, DOM, defer & async

Hoe 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.

1) Wat is “parsen”?

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
Belangrijk: Een “blokkerend” script kan het parsen (DOM opbouwen) even pauzeren. Met defer voorkom je dat.

2) Waar plaats je scripts?

  • Zonder attribuut (klassiek): browser stopt met HTML lezen, downloadt script en voert het meteen uit.
  • Met defer: downloadt parallel, blokkeert niet, voert pas uit als de HTML klaar is (vlak vóór DOMContentLoaded).
  • Met async: downloadt parallel en voert meteen uit zodra klaar (volgorde onvoorspelbaar).

defer — “download nu, voer later uit” ✅

  • Blokkeert de parser niet; scripts worden pas uitgevoerd als de DOM klaar is.
  • Behouden onderlinge volgorde zoals ze in het document staan.
  • Ideaal voor Bootstrap-bundle en je eigen scripts.
<!-- 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”

  • Volgorde t.o.v. andere scripts niet gegarandeerd.
  • DOMContentLoaded wacht niet op async scripts.
  • Gebruik voor onafhankelijke dingen (analytics, ads).
<script async src="/js/analytics.js"></script>

3) Vergelijking in één oogopslag

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

4) Best practices

  • Aanrader: zet externe scripts in <head> met defer.
  • Zet je script onderaan <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”.

5) Mini-oefening (volgorde testen)

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

6) Veelgemaakte fouten

  • Versies mixen: Bootstrap CSS/JS moeten dezelfde versie hebben.
  • Inline script met defer: werkt niet; defer geldt alleen voor externe scripts.
  • Cache vergeten: hard refresh (Ctrl/Cmd+Shift+R) of Network → “Disable cache”.
Ezelsbrug: async = “asap run”, defer = “later run (na HTML)”.