JavaScript in Head vs Footer: Come Influenza le Core Web Vitals

Perché il defer nell'head è la migliore pratica moderna e quando il posizionamento nel footer ha ancora senso

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-03

La risposta breve: defer nell'head

Ultima revisione di Arjen Karel a marzo 2026

Il consiglio classico era di inserire il JavaScript nel footer. Quel consiglio è obsoleto. Con async e defer supportati in tutti i browser, il posto migliore per la maggior parte degli script è all'interno del tag <head> con un attributo defer.

Il motivo si riduce al preload scanner: il tuo browser scopre gli script nell'head immediatamente e inizia a scaricarli in parallelo all'analisi (parsing) dell'HTML. Gli script nel footer vengono scoperti più tardi, il che significa un inizio ritardato del download. Il risultato è lo stesso comportamento non bloccante, ma con una scoperta delle risorse più rapida.

Secondo il 2025 Web Almanac, l'85% delle pagine fallisce ancora l'audit delle risorse che bloccano il rendering (render-blocking). È un numero enorme. Nel frattempo, il Total Blocking Time su mobile è aumentato del 58% su base annua, raggiungendo una mediana di 1.916 ms. Il JavaScript sta diventando più pesante, non più leggero. Posizionare correttamente gli script è una delle cose più semplici che puoi fare per migliorare il tuo First Contentful Paint e Largest Contentful Paint.

Come funziona il preload scanner

Il preload scanner è un secondo parser HTML che corre in anticipo rispetto al parser principale. Scansiona rapidamente l'HTML grezzo e inizia a recuperare le risorse critiche (immagini, CSS, JavaScript) prima che il parser principale le raggiunga. Il preload scanner recupera le risorse all'incirca nell'ordine in cui le scopre.

È qui che il posizionamento degli script è importante. Uno script all'interno dell'<head> viene scoperto quasi istantaneamente. Uno script in fondo al <body> viene scoperto più tardi, specialmente in documenti HTML di grandi dimensioni. Quel ritardo può costarti centinaia di millisecondi su una connessione mobile.

Gli script iniettati dinamicamente (creati tramite JavaScript) sono del tutto invisibili al preload scanner. Lo scanner scopre solo le risorse che esistono nel markup HTML restituito dal server. Questo è il motivo per cui differire il JavaScript tramite attributi HTML è quasi sempre meglio che iniettare script con il codice.

JavaScript nell'head

Posizionare il JavaScript all'interno del tag <head> della pagina consente al preload scanner di scoprirlo il prima possibile.

Vantaggi

  1. Scoperta precoce: Il preload scanner trova gli script nell'head prima di qualsiasi contenuto del body. Il download inizia il prima possibile.
  2. Esecuzione anticipata: Gli script nell'head (con defer) vengono eseguiti prima degli script scoperti più tardi nel documento. Per un confronto dettagliato, vedi defer vs async JavaScript e le Core Web Vitals.
  3. Separazione del codice: Mantenere i riferimenti agli script all'interno dell'<head> li separa dal markup dei contenuti, rendendo l'HTML più facile da mantenere.

Svantaggi

  1. Blocco del rendering (senza defer o async): Un semplice <script> nell'head blocca l'analisi dell'HTML fino a quando lo script non viene scaricato ed eseguito. Questo distrugge il tuo First Contentful Paint. Usa sempre defer o async sugli script esterni nell'head per evitarlo.
  2. Competizione per la larghezza di banda: Gli script nell'head con priorità elevata competono per la larghezza di banda con CSS, font e l'immagine LCP. Su connessioni più lente, questo può spingere il tuo Largest Contentful Paint oltre la soglia di 2,5 secondi.

Quando usare il posizionamento nell'head

Usa l'<head> per gli script che sono critici per l'esperienza della pagina: il tuo menu, l'avviso sui cookie, lo slider o qualsiasi script che influenzi ciò che il visitatore vede above the fold (nella parte visibile senza scorrere). Aggiungi defer (o async se l'ordine di esecuzione non ha importanza) per prevenire il blocco del rendering. Anche le librerie di rilevamento delle funzionalità (feature detection) vanno inserite nell'head, poiché devono essere eseguite prima che il body venga analizzato.

JavaScript nel footer

Posizionare il JavaScript appena prima del tag di chiusura </body> è stato il consiglio standard sulle prestazioni per anni. L'idea: lasciare che l'HTML venga renderizzato per primo, scaricare gli script dopo.

Vantaggi

  1. Non bloccante per impostazione predefinita: Gli script nel footer non bloccano il rendering iniziale perché l'HTML sopra di essi è già stato analizzato.
  2. Minore competizione per la larghezza di banda: Nel momento in cui il browser raggiunge gli script nel footer, i CSS, i font e l'immagine LCP hanno già iniziato il download.

Svantaggi

  1. Scoperta tardiva: Il preload scanner trova gli script nel footer più tardi rispetto agli script nell'head. In una pagina grande, questo significa un inizio del download posticipato e un'esecuzione ritardata.
  2. Modello obsoleto: <script defer> all'interno dell'<head> ottiene lo stesso comportamento non bloccante con una scoperta anticipata. Il posizionamento nel footer era la soluzione alternativa (workaround) prima che defer avesse un supporto universale nei browser. Quell'era è finita.

Quando il posizionamento nel footer ha ancora senso

Il posizionamento nel footer può avere senso per gli script di cui non desideri assolutamente la competizione per la larghezza di banda durante il caricamento iniziale della pagina: analytics, strumenti di A/B testing o widget social. Ma anche per questi, l'utilizzo di defer nell'head è solitamente la scelta migliore grazie alla scoperta anticipata da parte del preload scanner.

Attributi script moderni

Oltre ad async e defer, ci sono altri due attributi che vale la pena conoscere:

type="module": Gli script modulo sono differiti di default. Non c'è bisogno di aggiungere defer a uno script modulo perché si comporta già in quel modo. Aggiungendo async a uno script modulo, si sovrascrive il comportamento defer predefinito, facendolo eseguire non appena termina il download.

fetchpriority: Per impostazione predefinita, gli script async e defer ottengono una bassa priorità di rete. Aggiungendo fetchpriority="high" a uno script async si ottiene un download non bloccante con priorità alta. Questa è la combinazione ideale per gli script che sono critici per l'esperienza utente ma non dovrebbero bloccare il rendering. Per il quadro completo, vedi la guida alla priorità delle risorse e i livelli di priorità del JavaScript.

Una strategia pratica per il posizionamento degli script

Non tutti gli script meritano lo stesso trattamento. Io uso un approccio su quattro livelli:

  1. Script critici per il rendering: Script che influenzano il layout visibile della pagina (menu, slider, interfaccia utente above the fold). Inseriscili nell'<head> senza defer se devono assolutamente essere eseguiti prima del first paint. Mantienili il più piccoli possibile perché bloccano il rendering e danneggeranno le tue Core Web Vitals.
  2. Script importanti: Script critici per la conversione o l'interazione (moduli, navigazione, consenso ai cookie). Inseriscili nell'<head> con defer o async.
  3. Script normali: Script che non influenzano il primo rendering della pagina (caroselli, finestre modali, schede). Inseriscili nell'<head> con defer.
  4. Script "nice-to-have" (non essenziali): Script di cui potresti fare a meno se fossi assolutamente costretto (analytics, widget di chat, condivisione sui social). Caricali dopo che la pagina ha finito di renderizzare, usando l'evento load o requestIdleCallback. Consulta 16 metodi per differire il JavaScript per scoprire le varie tecniche. Se hai molto JavaScript non utilizzato in questa categoria, vedi come ridurre il JavaScript non utilizzato.

Gli eventi DOMContentLoaded e load ti permettono di controllare il momento dell'esecuzione, indipendentemente da dove lo script sia posizionato nell'HTML. Questo è utile per garantire che il tuo codice venga eseguito nel momento giusto.

Esempi di codice

Esempio 1: JavaScript nell'head (blocca il rendering)

<!DOCTYPE html>
<html>
<head>
    <title>Esempio JavaScript nell'Head</title>
    <script>
        function showMessage() {
            alert("Ciao dal JavaScript nell'head!");
        }
    </script>
    <!-- Questo script blocca il rendering -->
    <script src="script.js"></script>
</head>
<body>
    <button onclick="showMessage()">Cliccami</button>
</body>
</html>

In questo esempio, script.js all'interno dell'<head> blocca il rendering. Il browser non mostrerà il pulsante finché lo script non sarà stato scaricato ed eseguito. Aggiungi defer al tag dello script per risolverlo.

Esempio 2: JavaScript nel footer

<!DOCTYPE html>
<html>
<head>
    <title>Esempio JavaScript nel Footer</title>
</head>
<body>
    <button onclick="showMessage()">Cliccami</button>
    <!-- Script alla fine del body -->
    <script src="script.js"></script>
    <script>
        function showMessage() {
            alert("Ciao dal JavaScript nel footer!");
        }
    </script>
</body>
</html>

Qui, script.js viene caricato dopo i contenuti HTML, in modo da non bloccare il rendering. Ma il preload scanner lo scopre più tardi rispetto a quando si troverebbe nell'head. Usare <script defer src="script.js"></script> all'interno dell'<head> garantisce lo stesso comportamento non bloccante con una scoperta del download più precoce.

Esempio 3: Usare gli event listener

<!DOCTYPE html>
<html>
<head>
    <title>Esempio Event Listener</title>
    <script>
        window.addEventListener('load', function() {
            console.log("La pagina è completamente caricata.");
        });
    </script>
</head>
<body>
    <!-- Contenuto della pagina -->
</body>
</html>

L'event listener load garantisce che il codice all'interno del callback venga eseguito solo dopo che la pagina è stata caricata completamente, indipendentemente da dove viene posizionato lo script. È una soluzione utile per le inizializzazioni non critiche che dovrebbero aspettare fino a quando tutto il resto è pronto.

Verifica i tuoi cambiamenti

Dopo aver spostato gli script dal footer a defer nell'<head>, verifica l'impatto con il Real User Monitoring. Il tuo FCP e LCP dovrebbero entrambi migliorare. Nei siti monitorati da CoreDash, le origini che usano defer per la maggior parte dei loro script hanno una mediana di FCP più veloce del 18% rispetto alle origini che si basano ancora sul posizionamento nel footer.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Performance degrades unless you guard it.

I do not just fix the metrics. I set up the monitoring, the budgets, and the processes so your team keeps them green after I leave.

Start the Engagement
JavaScript in Head vs Footer: Come Influenza le Core Web VitalsCore Web Vitals JavaScript in Head vs Footer: Come Influenza le Core Web Vitals