defer ja async muuttavat milloin ulkoinen <script> ladataan ja suoritetaan suhteessa HTML-jäsentämiseen. Molemmat sallivat skriptin lataamisen rinnakkain ilman jäsentäjän estämistä — ero on suorituksen ajoituksessa.
html
defer ja async muuttavat milloin ulkoinen <script> ladataan ja suoritetaan suhteessa HTML-jäsentämiseen. Molemmat sallivat skriptin lataamisen rinnakkain ilman jäsentäjän estämistä — ero on suorituksen ajoituksessa.
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 | |
|---|---|---|
| Lataus | rinnakkain | rinnakkain |
| Suoritus | heti kun ladattu | kun HTML on kokonaan jäsennetty |
| Järjestys säilyy? | Ei (kuka valmistuu ensin) | Kyllä (dokumentin järjestys) |
| Estää jäsentäjän? | vain lyhyesti suorituksen aikana | ei koskaan |
defer — skripteille, jotka käsittelevät DOM:ia tai riippuvat toisistaan/järjestyksestä (sovelluskoodisi). Ne suoritetaan kun DOM on olemassa, järjestyksessä, juuri ennen DOMContentLoaded-tapahtumaa.async — itsenäisille kolmannen osapuolen skripteille, jotka eivät riipu DOM:ista tai muista skripteistä (analytiikka, mainokset). Järjestys ei merkitse, suorita ne mahdollisimman pian.<script src="analytics.js" async></script> <!-- independent → async -->
<script src="app.js" defer></script> <!-- app logic, ordered → defer -->
Huomio: molemmat pätevät vain ulkoisiin skripteihin (src); ne jätetään huomiotta inline-skripteissä. ES-moduulit (type="module") ovat oletusarvoisesti deferred.
defer/async-attribuuttien käyttö estää skriptejä estämästä HTML-jäsentämistä, mikä parantaa suoraan lataussuorituskykyä ja First Contentful Paintia.
Oikean valinnan tekeminen (defer järjestykseltään riippuvaiselle DOM-koodille, async palota ja unohda -tyyppisille kolmannen osapuolen skripteille) välttää sekä hitaat lataukset että järjestysriippuvuusvirheet.