Attiva «Ritarda l'esecuzione di JavaScript», il report PageSpeed fa un balzo, e poi arrivano i messaggi. Il menu mobile non fa nulla. Il banner dei cookie non si chiude. Il modulo di contatto continua a caricare. Lo slider della home è vuoto. La bolla della chat è sparita. Oppure, una settimana dopo, le statistiche mostrano un calo di sessioni che nessuno sa spiegare.
Il consiglio abituale è una lista di esclusioni da incollare, oppure spegnere l'opzione. Entrambe le cose funzionano, ed entrambe buttano via il guadagno senza dirle cosa si è davvero rotto. Questa guida le dà invece il metodo: perché il ritardo rompe le cose, come leggere il sintomo e come trovare l'unico script da togliere.
Cosa fa il ritardo a una pagina
Normalmente, ogni script della pagina viene scaricato ed eseguito durante il caricamento. Con un ritardo di JavaScript, gli script vengono parcheggiati: i loro tag vengono riscritti perché il browser li ignori. Un piccolo loader aspetta che il visitatore faccia qualcosa (muovere il mouse, scorrere, toccare lo schermo, premere un tasto), o che scada un timer, e solo allora rimette gli script al loro posto, uno dopo l'altro.
Ecco perché il punteggio di laboratorio sale: durante il test non gira quasi nessun JavaScript. Ed ecco perché qualcosa si rompe: ogni script ora gira più tardi, in una pagina che ha già finito di caricare, e solo se il loader arriva fin lì.
I cinque modi in cui si rompe, e la loro firma
1. Manca una dipendenza. Uno script è escluso dal ritardo (quindi gira al caricamento) ma qualcosa di cui ha bisogno è ancora parcheggiato. Il caso classico: uno script del menu gira quando jQuery non esiste ancora. Firma: un errore rosso nella console, per esempio jQuery is not defined, $ is not a function o Cannot read properties of undefined.
2. L'evento della pagina è già scattato. Molti script aspettano DOMContentLoaded o window.onload prima di partire. Quando arriva uno script ritardato, quegli eventi sono passati da un pezzo, quindi il suo codice di avvio aspetta qualcosa che non succederà mai. Firma: nessun errore, la funzione semplicemente non parte mai. Slider, gallerie e lightbox sono vittime frequenti.
3. Il primo clic viene inghiottito. Il primo tocco del visitatore è l'interazione che sveglia il loader. Gli script non ci sono ancora quando arriva quel tocco, quindi non fa nulla. Firma: funziona sempre al secondo tocco. Abbiamo trattato questo caso nel dettaglio nella guida sul menu hamburger.
4. La catena è bloccata su uno script. Gli script ritardati di solito vengono rimessi in ordine, uno dopo l'altro, perché le dipendenze continuino a funzionare. Se uno di loro resta trattenuto (un ad blocker, un filtro DNS o un proxy aziendale che non risponde né rifiuta), tutto ciò che viene dopo aspetta per sempre. Firma: intermittente, solo per alcuni visitatori, mai sul suo computer. Spesso sono le funzioni del footer a morire.
5. Il visitatore non viene mai contato. Se il tag di analytics è ritardato, un visitatore che legge la pagina e se ne va senza interagire (e prima del timer) non lo carica mai. Firma: nessun difetto visibile, solo meno sessioni e una quota più alta di visite brevi che manca nei report.
Passo 1: confermare che la causa è il ritardo
Spenga il ritardo, svuoti ogni livello di cache (cache di pagina, cache dell'hosting, CDN) e riprovi in una finestra privata. Se la funzione va, la causa è il ritardo. Se fallisce ancora, si fermi qui: il problema è altrove, spesso un'ottimizzazione CSS che ha tolto gli stili di un elemento nascosto (veda la guida sul critical CSS).
Poi lo riattivi e riproduca il bug come si deve:
- Emulazione mobile nei DevTools, non la sua vista desktop. Molte configurazioni tengono una versione ottimizzata separata per dispositivo.
- Una finestra privata pulita, senza estensioni, per vedere ciò che vede un visitatore nuovo.
- Tocchi per primo l'elemento rotto, senza muovere il mouse né scorrere prima. È l'unico modo per vedere il caso 3.
- Poi ancora una volta con un ad blocker attivo, per far emergere il caso 4.
Passo 2: trovare lo script dietro la funzione rotta
Apra i DevTools prima di riprodurre il bug, poi guardi in tre punti.
La console. Qualsiasi errore rosso dopo la sua interazione indica il caso 1, e il nome del file a destra dell'errore è il suo primo sospettato. Ci clicchi sopra: i DevTools mostrano la riga esatta.
Gli event listener dell'elemento. Clic destro sul pulsante rotto, scelga Ispeziona, poi apra il pannello Event Listeners. Elenca ogni handler collegato all'elemento e il file che lo ha collegato. Se l'elenco è vuoto dopo la sua interazione, lo script che doveva collegare l'handler non è mai partito (caso 2 o 4).
Una ricerca in tutti i file caricati. Nel pannello Sources, cerchi in tutti i file (Ctrl+Maiusc+F, o Cmd+Option+F su Mac) la classe o l'id dell'elemento rotto, per esempio menu-toggle o cky-btn-accept. Il file che lo cita è quello che lo pilota.
// Da incollare nella console a pagina caricata, prima di qualsiasi interazione,
// poi di nuovo dopo il primo clic. Adatti il tipo al markup del suo strumento.
[...document.querySelectorAll('script[type]')]
.filter(s => !/^(text|application)\/(javascript|ld\+json|json)$|^module$/.test(s.type))
.map(s => s.src || s.dataset.src || (s.textContent || '').slice(0, 60))Se lo script individuato è ancora in quell'elenco dopo la sua interazione, la catena non l'ha mai raggiunto: guardi cosa c'è subito prima (caso 4).
Passo 3: escludere tutta la catena, non solo il file
Uno script raramente lavora da solo. Prima di escluderlo, elenchi ciò di cui ha bisogno, nell'ordine in cui compare nel sorgente della pagina:
- Le sue librerie: jQuery, e a volte jQuery Migrate o lo script principale del tema.
- La sua configurazione: WordPress stampa spesso un piccolo script inline subito prima del file, con un id che finisce in
-js-extra(per esempiovar wpcf7 = {...}per Contact Form 7). Senza di esso il file non può girare. - Il suo file, per ultimo.
Li escluda insieme, e punti a ciascuno con un frammento unico del suo URL (come /contact-form-7/ o jquery.min.js) invece che con una parola generica. Un frammento come slider può corrispondere a molti più file di quanto pensi, e ogni corrispondenza in più restituisce parte del guadagno.
Passo 4: quando non lo trova, divida a metà
Su una pagina pesante con 60 script ritardati, leggerli uno per uno richiede un pomeriggio. Dividere a metà richiede sei test. Escluda la prima metà degli script ritardati e provi. Se la funzione va, il colpevole è in quella metà; altrimenti è nell'altra. Divida ancora, e ancora: 60, 30, 15, 8, 4, 2, 1.
Due regole lo rendono affidabile: svuoti ogni livello di cache tra un test e l'altro, e tenga jQuery con la metà che lo contiene, altrimenti ogni test fallirà per il motivo sbagliato.
I soliti sospetti, famiglia per famiglia
Menu, accordion, schede. Escluda la catena (jQuery più lo script del tema), oppure dia al menu un piccolo script autonomo. Il compromesso è spiegato nella guida sul menu hamburger, e perché il menu a volte condivide un file con il resto del tema nella guida sugli script di tema monolitici.
Banner dei cookie e strumenti di consenso. Non li ritardi. Il banner deve essere subito utilizzabile, e il consenso deve essere registrato prima che un tag decida cosa caricare. Questi script sono piccoli, escluderli costa poco. Se i suoi tag usano la modalità di consenso, anche lo stato predefinito deve essere impostato prima che i tag partano. Per Axeptio in particolare, veda come velocizzare il caricamento di Axeptio.
Moduli e captcha. Escluda la catena del plugin dei moduli sulle pagine che hanno un modulo, non su tutto il sito. Un captcha che si carica solo quando il visitatore inizia a scrivere è un buon compromesso.
Slider e tutto ciò che si vede senza scorrere. Se è la prima cosa che vede il visitatore, ritardarlo dà un hero vuoto o senza stile, e spesso un Largest Contentful Paint peggiore. Nulla di visibile al caricamento dovrebbe essere ritardato, solo ciò che sta più in basso.
Widget di chat e pop-up. Sono esattamente ciò per cui esiste il ritardo. Li lasci ritardati. Se il pulsante di avvio deve essere visibile senza interazione, dia a quel solo script un timer breve invece di escluderlo.
Analytics e tag. Ritardarli rende poco con un tag ben configurato e costa dati. Lo decida consapevolmente: o il tag carica presto e ogni visita conta, o aspetta e lei accetta di contare solo i visitatori che interagiscono.
Esclusione mirata
Una catena, identificata per URL, sui template che la usano. Il resto della pagina resta ritardato e il guadagno è conservato.
Esclusione ampia
«Escludere jQuery ovunque», una parola chiave generica o una modalità sicura che ricarica tutto presto. Il bug è sparito, e con lui la maggior parte del guadagno.
Dopo la correzione: controllare ciò che non si vede
- Provi ancora una volta con un ad blocker: una correzione che funziona solo in un browser pulito resta rotta per una parte dei suoi visitatori.
- Confronti una settimana di sessioni prima e dopo l'attivazione del ritardo. Un calo senza una ragione di traffico è il caso 5.
- Riprovi dopo ogni aggiornamento di tema o plugin: i nomi dei file cambiano, e un'esclusione per URL può smettere di corrispondere.
- E segua l'ordine che mantiene un sito al sicuro: prima le ottimizzazioni innocue, quelle rischiose una alla volta, come nel nostro metodo per ottimizzare senza rompere.
Con Mantys Core
Mantys Core può gestire l'intero livello di performance, cache inclusa, oppure affiancarsi alla configurazione già in uso. Il suo ritardo di JavaScript è costruito attorno alle rotture descritte sopra:
Il codice di avvio degli strumenti di consenso più diffusi, il tag manager e il tag di analytics sono esclusi dal ritardo per impostazione predefinita, quindi lo stato del consenso e i tag partono al caricamento. Se il banner carica un proprio file da uno script separato, va aggiunto alle eccezioni.
Gli script ritardati vengono rimessi nell'ordine della pagina, quindi una libreria gira sempre prima di ciò che ne dipende.
Uno script trattenuto da un filtro o da un proxy non può congelare il resto: dopo una breve attesa, la catena passa al successivo.
Un'interazione che arriva mentre la pagina sta ancora caricando aspetta la pagina intera, quindi nessuno script in fondo viene lasciato indietro.
Le eccezioni si dichiarano per frammento di URL e si possono impostare per template: lo script dello slider è escluso solo sulla home e resta ritardato ovunque altrove.
I servizi di terze parti indipendenti possono avere un proprio timer breve invece di un'esclusione completa.
Lei continua a decidere ciò che conta su ogni pagina. La piattaforma fa in modo che un'esclusione resti un'esclusione.
In sintesi
- Un ritardo di JavaScript esegue ogni script più tardi, in una pagina già caricata, e solo se il loader arriva fin lì.
- Cinque rotture, cinque firme: un errore in console, una funzione che non parte mai, un secondo tocco, un guasto solo per alcuni visitatori e meno sessioni.
- Confermi con il ritardo spento, poi trovi lo script tramite la console, gli event listener dell'elemento e una ricerca nei file.
- Escluda tutta la catena (libreria, configurazione inline, file) per frammento di URL, e solo dove serve. Divida a metà quando non trova il colpevole.
- Non ritardi mai lo strumento di consenso né nulla di visibile al caricamento; lasci ritardati i widget di chat e i pop-up.
Commenti
È bloccato su un problema simile? Descriva la sua configurazione e ciò che osserva. Leggiamo ogni commento e rispondiamo.
Ancora nessun commento. Condivida per primo il suo caso.