Tra le ottimizzazioni più diffuse degli ultimi anni ce n’è una che promette risultati spettacolari con un solo interruttore: ritardare l’esecuzione del JavaScript fino alla prima interazione dell’utente. La offrono, con nomi diversi, quasi tutti i plugin di performance per WordPress, e il suo effetto sui punteggi di laboratorio è immediato: il Total Blocking Time crolla, il punteggio di Lighthouse sale, il cerchio diventa verde.
Il problema è che il JavaScript ritardato non smette di esistere. Il lavoro che non avviene durante il caricamento avverrà più tardi, e il momento scelto per eseguirlo è il peggiore possibile: l’istante in cui l’utente ha appena toccato lo schermo e si aspetta una risposta. In questo articolo vediamo come funziona la tecnica, perché migliora i test, che cosa rompe e quando ha davvero senso usarla.
Come funziona il delay al primo clic
Il principio è semplice. Durante la generazione della pagina il plugin riscrive i tag script in modo che il browser non li riconosca come codice da eseguire: il tipo diventa un valore inventato e l’indirizzo del file viene spostato dall’attributo src a un attributo di comodo. Un piccolo loader, l’unico script eseguito subito, resta in ascolto di eventi come movimento del mouse, tocco, scorrimento o pressione di un tasto. Alla prima interazione ripristina i tag originali e li esegue, uno dopo l’altro, nell’ordine in cui comparivano nella pagina.
<!-- come lo scrive il tema -->
<script src="/wp-content/plugins/slider/slider.js"></script>
<!-- come lo serve il plugin di ottimizzazione -->
<script type="delayed/javascript" data-src="/wp-content/plugins/slider/slider.js"></script>
Alcune implementazioni prevedono un timer di sicurezza che carica comunque gli script dopo qualche secondo, altre no: senza interazione, il JavaScript ritardato non viene mai eseguito. È un dettaglio che cambia molto il comportamento del sito, e vale sempre la pena verificarlo nella propria configurazione.
Perché i punteggi migliorano così tanto
Lighthouse carica la pagina e la osserva, ma non la usa: non muove il mouse, non scorre, non tocca menu o pulsanti. Con il delay attivo, quindi, per tutta la durata del test il JavaScript ritardato non viene né scaricato né eseguito. Il thread principale resta libero, il Total Blocking Time scende a valori vicini allo zero e, se alcuni script ostacolavano il rendering, anche FCP e LCP migliorano.
Il test misura correttamente ciò che vede. Ma ciò che vede è una pagina in cui una parte del codice non è mai entrata in gioco. È un risultato vero per il laboratorio e fuorviante per il business, perché nessun utente reale si limita a guardare una pagina senza toccarla.
Il lavoro non sparisce: si sposta sull’INP
Dal 2024 la reattività della pagina è misurata dall’INP (Interaction to Next Paint), che rileva quanto tempo passa tra un’interazione dell’utente e il successivo aggiornamento dello schermo, e riporta il valore di una delle interazioni peggiori della visita. È proprio la metrica su cui il delay al primo clic scarica il suo costo.
Quando l’utente tocca per la prima volta la pagina, il browser deve fare tutto insieme: scaricare gli script ritardati, analizzarli, compilarli ed eseguirli in sequenza, spesso inizializzando slider, widget, tracciamenti e librerie in un unico blocco di lavoro. Su un computer recente può trattarsi di qualche centinaio di millisecondi; su uno smartphone di fascia media, con una connessione mobile, di un secondo o più. Durante quel tempo la pagina non risponde: il menu non si apre, il pulsante non reagisce, il testo digitato non compare.
Il risultato, sui dati degli utenti reali, è un INP peggiore proprio sulle pagine che in laboratorio sembrano perfette. E poiché l’INP è uno dei tre Core Web Vitals valutati da Google sui dati del Chrome UX Report, il miglioramento del punteggio di laboratorio può coesistere con un peggioramento della valutazione che conta davvero.
Che cosa si rompe
Oltre alla reattività, il delay generalizzato ha effetti collaterali funzionali che emergono solo nell’uso reale:
- Il primo tocco va perso. Se il menu mobile, un filtro o un pulsante “aggiungi al carrello” dipendono da uno script ritardato, la prima interazione serve solo a caricarlo. L’utente tocca, non succede nulla, tocca di nuovo. Alcuni loader provano a ripetere il clic, ma non sempre ci riescono.
- Componenti che cambiano aspetto. Slider, caroselli, schede e fisarmoniche si presentano nella loro forma “senza JavaScript” e si trasformano al primo movimento del mouse, con salti di layout che peggiorano il CLS.
- Consenso ai cookie in ritardo. Se il banner del consenso è tra gli script ritardati, compare solo dopo la prima interazione, con evidenti problemi sia di esperienza sia di conformità.
- Funzioni che dipendono dall’ordine. Script inline che si aspettano una libreria già caricata, codice legato all’evento
DOMContentLoadedche nel frattempo è già passato, integrazioni che si inizializzano due volte: sono i bug più difficili da riprodurre, perché dipendono da come e quando l’utente interagisce.
L’effetto nascosto sui dati di marketing
C’è poi una conseguenza che raramente viene considerata quando si attiva il delay: gli strumenti di analisi e i pixel pubblicitari sono script come gli altri. Se vengono ritardati, una visita senza interazioni non viene registrata affatto. Chi arriva da una campagna, legge l’inizio della pagina e se ne va senza toccare nulla semplicemente non esiste nei report.
Le conseguenze si propagano a catena. La frequenza di rimbalzo appare migliore di quella reale, perché i rimbalzi più rapidi spariscono. I tassi di conversione risultano gonfiati, perché il denominatore si riduce. Le piattaforme pubblicitarie ricevono meno segnali e ottimizzano le campagne su dati parziali. Un’ottimizzazione nata per migliorare un punteggio finisce così per alterare le metriche su cui si prendono decisioni di budget.
Quando il delay ha senso
Il delay non è una tecnica da demonizzare, ma da usare in modo selettivo. Funziona bene per il codice che non serve alla prima interazione e che l’utente può tranquillamente attendere:
- chat di assistenza e widget di messaggistica;
- strumenti di registrazione delle sessioni e mappe di calore;
- widget social, recensioni incorporate e contenuti di terze parti sotto la piega;
- video e mappe incorporati, meglio ancora se sostituiti da un’anteprima statica che carica il player solo al clic.
Tutto ciò che riguarda navigazione, consenso, misurazione di base e funzioni commerciali principali va invece escluso. In pratica significa rovesciare l’approccio predefinito di molti plugin: non “ritardo tutto tranne le eccezioni”, ma “ritardo solo ciò che ho verificato essere superfluo al primo impatto”.
Le alternative che riducono davvero il lavoro
Il modo più efficace per non pagare il costo del JavaScript è non doverlo eseguire. Prima di ritardare, conviene chiedersi quanto codice è davvero necessario e dove:
- Rimuovere. Plugin inutilizzati, librerie duplicate, funzioni attivate “per sicurezza” e mai usate: è il guadagno più grande e più stabile.
- Caricare solo dove serve. Lo script del configuratore di prodotto non deve essere presente negli articoli del blog, quello del modulo di contatto non deve comparire nelle schede prodotto.
- Usare correttamente defer e async. Gli script con
defernon bloccano il rendering e vengono eseguiti in ordine a documento pronto, senza attendere un’interazione che potrebbe non arrivare mai. - Caricare in base alla visibilità. Con
IntersectionObserverun componente sotto la piega può inizializzarsi quando sta per entrare nello schermo, non al primo movimento del mouse. - Spezzare i task lunghi. Il lavoro inevitabile può essere suddiviso in blocchi più piccoli, restituendo periodicamente il controllo al browser, così che le interazioni dell’utente non restino in coda.
Come misurarne l’effetto reale
Poiché il costo del delay si manifesta solo quando qualcuno usa la pagina, va misurato sugli utenti reali o simulando un’interazione. In laboratorio, il pannello Performance dei DevTools di Chrome, con la CPU rallentata di quattro volte, permette di registrare il primo tocco su un pulsante e di osservare quanto dura il blocco di lavoro che ne segue.
Sul campo, la libreria open source web-vitals nella sua versione con attribuzione indica quale interazione ha prodotto l’INP peggiore, su quale elemento e quanto tempo è stato speso in attesa, in elaborazione e nel disegno successivo:
import { onINP } from 'web-vitals/attribution';
onINP( ( { value, attribution } ) => {
console.log( 'INP', Math.round( value ), 'ms', {
elemento: attribution.interactionTarget,
attesa: attribution.inputDelay,
elaborazione: attribution.processingDuration,
disegno: attribution.presentationDelay,
} );
} );
Se il primo clic mostra un tempo di attesa molto lungo e l’elemento coinvolto è sempre il primo toccato dall’utente, il responsabile è quasi certamente il caricamento in blocco degli script ritardati. Il confronto definitivo arriva poi dai dati CrUX: l’INP al 75° percentile, prima e dopo l’attivazione del delay, su due finestre complete di 28 giorni.
In sintesi
Il delay del JavaScript al primo clic migliora molto i punteggi di laboratorio perché il test non interagisce con la pagina. Per gli utenti reali, invece, il lavoro rinviato si concentra nel momento del primo tocco, peggiora l’INP, può rendere inefficaci menu e pulsanti, far comparire in ritardo il consenso ai cookie e sottrarre ai report proprio le visite più brevi.
Usato con criterio, su script di terze parti non essenziali e con esclusioni ben definite, resta uno strumento utile. Ma non sostituisce il lavoro che produce risultati duraturi: eliminare il codice superfluo, caricarlo solo dove serve e fare in modo che quello necessario non blocchi il thread principale. Rinviare il lavoro non significa eliminarlo, e alla fine qualcuno lo paga: l’utente.