Attributo defer HTML
L'attributo defer HTML specifica che uno script viene eseguito al termine del parsing della pagina. Scopri come usarlo sull'elemento <script>.
L'attributo HTML defer è un attributo boolean sull'elemento <script> che indica al browser di scaricare lo script in parallelo con il parsing HTML, ma di attendere ed eseguirlo solo dopo che l'intera pagina ha terminato il parsing — immediatamente prima che venga attivato l'evento DOMContentLoaded.
Funziona solo con script esterni: ha effetto solo quando l'attributo src è presente e viene ignorato negli script inline (un <script> il cui codice JavaScript si trova tra i tag).
Perché esiste l'attributo defer
Un semplice <script src="..."> è render-blocking. Quando il parser lo incontra, smette di costruire la pagina, scarica il file, lo esegue e solo allora continua. Se lo script si trova nel <head>, l'utente vede una pagina bianca fino al suo caricamento.
Il metodo classico per aggirare questo problema era inserire i tag <script> alla fine del <body>, in modo che l'HTML venisse analizzato per primo. defer rende questo espediente superfluo: puoi mantenere gli script nel <head> (utile per la leggibilità e affinché il browser li scopra e li scarichi anticipatamente), mentre lo script viene comunque eseguito solo dopo che il DOM è stato completamente costruito. Poiché il DOM è garantito essere pronto, gli script differiti possono interrogare gli elementi in sicurezza senza dover racchiudere tutto in un listener DOMContentLoaded.
defer vs async
Sia defer che async consentono al browser di scaricare lo script in background senza bloccare il parsing HTML. La differenza sta nel quando e nell'ordine in cui gli script vengono eseguiti:
| Comportamento | defer | async |
|---|---|---|
| Blocca il parsing HTML durante il download | No | No |
| Quando viene eseguito lo script | Dopo il completamento del parsing, appena prima di DOMContentLoaded | Non appena termina il download (può interrompere il parsing) |
| Ordine di esecuzione rispetto ad altri script | Garantito — eseguito nell'ordine del documento | Non garantito — chi finisce prima il download viene eseguito prima |
| DOM garantito pronto | Sì | No |
Usa defer quando gli script dipendono dal DOM o l'uno dall'altro (l'ordine è importante). Usa async per script indipendenti e autonomi come analytics o tag pubblicitari, dove l'ordine non ha importanza e vuoi che ognuno venga eseguito nel momento in cui arriva.
Se non è presente né async né defer, lo script viene recuperato ed eseguito immediatamente, bloccando il parser in quel punto.
In HTML 4.01 il comportamento di defer dipendeva dall'implementazione, mentre HTML5 lo ha standardizzato. In XHTML, defer deve essere scritto come <script defer="defer"> perché la minimizzazione degli attributi è vietata.
Sintassi
<script src="example.js" defer></script>Esempio dell'attributo defer HTML
Lo script seguente è inserito nel <head>, ma poiché è differito viene eseguito solo dopo che il paragrafo esiste nel DOM — quindi document.getElementById lo trova:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
defer
></script>
<noscript>Sorry, your browser doesn't support JavaScript!</noscript>
</head>
<body>
<h1>Example</h1>
<p id="demo">Waiting for the deferred script...</p>
<script defer>
// This deferred external script (jQuery) is already loaded,
// and the DOM is fully parsed, so the line below works.
document.getElementById("demo").textContent =
"jQuery version " + jQuery.fn.jquery + " ran after parsing.";
</script>
</body>
</html>Nota:
defersullo<script>inline qui sopra viene ignorato — gli script inline vengono sempre eseguiti al loro posto. Funziona in questo caso solo perché è l'ultimo elemento e lo script esterno differito ha già terminato. Per garantire che una libreria esterna differita sia caricata prima del proprio codice, inserisci anche il tuo codice in un file esterno condefer, poiché gli script differiti vengono eseguiti nell'ordine del documento.