Il contesto
Telebari è un’emittente televisiva regionale con sede a Bari. Il suo sito, realizzato con WordPress, pubblica ogni giorno notizie di cronaca, politica, sport e attualità dal territorio, con un archivio che cresce di continuo. È il profilo tipico di un sito editoriale: molte pagine costruite su pochi modelli, picchi di traffico legati alle notizie del momento e lettori che arrivano in gran parte da smartphone, spesso dai social e da Google Discover.
Il sito girava su un server LiteSpeed con il plugin LSCache, che gestiva sia la cache delle pagine sia le ottimizzazioni del front-end: combinazione e caricamento asincrono del CSS, generazione automatica degli stili, ottimizzazione di font e immagini. Un’impostazione comoda, in cui però molte decisioni erano affidate a elaborazioni automatiche, pagina per pagina.
Cosa dicevano i dati
Nei dati degli utenti reali le Core Web Vitals da mobile non risultavano superate, con un LCP al 75° percentile intorno ai 3,6 secondi e un CLS di 0,24. Le prove in laboratorio su mobile confermavano il quadro: First Contentful Paint a 3,2 secondi, Largest Contentful Paint a 6,4 secondi, Total Blocking Time a 540 millisecondi, Cumulative Layout Shift a 0,31 e Speed Index a 5,1 secondi.
Oltre ai numeri, il problema era visibile a occhio nudo. All’apertura di una pagina il contenuto compariva prima senza stili, o con stili parziali, e poi si ricomponeva: menu, testate e blocchi di notizie cambiavano forma e posizione con un evidente sfarfallio. Un glitch sgradevole per i lettori e poco coerente con l’immagine di una testata giornalistica.
La diagnosi
L’analisi ha ricondotto lo sfarfallio e il CLS a poche cause, che si sommavano:
- CSS caricato in modo asincrono senza un CSS critico adeguato: la pagina veniva disegnata con stili incompleti e ricomposta quando arrivava il resto del CSS;
- font web pesanti e non ottimizzati, che sostituivano quelli di riserva con metriche diverse e facevano scorrere i testi a caricamento avvenuto;
- elementi senza spazio riservato, come immagini, banner e blocchi caricati in un secondo momento;
- risorse critiche scoperte tardi: l’immagine principale e i font venivano richiesti solo dopo l’analisi del CSS, ritardando l’LCP.
Gli interventi sul server
Il primo passo è stato spostare la cache delle pagine dal plugin al server. Il sito è stato migrato da LiteSpeed con LSCache a NGINX con Varnish Cache davanti, e con un’invalidazione mirata: alla pubblicazione o all’aggiornamento di un articolo si svuotano solo quell’articolo, la home page e le categorie coinvolte, non l’intero sito. Le pagine più lette restano sempre in cache, quelle d’archivio vi entrano alla prima visita, e la risposta del server è diventata veloce e prevedibile anche durante i picchi di traffico.
Gli interventi sull’applicazione
Sul front-end abbiamo rinunciato alle ottimizzazioni automatiche e lavorato a mano, per modello di pagina:
- CSS critico generato e verificato per home page, categorie e articoli, in linea nell’intestazione, con il resto del CSS caricato senza bloccare il rendering e senza ricomposizioni visibili;
- subsetting dei font, riducendo i file ai soli caratteri necessari e allineando le metriche dei font di riserva, così che la sostituzione non sposti più i testi;
- preload e preconnect mirati, solo per le risorse davvero critiche come l’immagine principale e i font, e per le origini da cui dipendono;
- spazio riservato per immagini, banner e blocchi caricati in un secondo momento.
I risultati
Il confronto delle prove in laboratorio su mobile, prima e dopo gli interventi:
| Metrica (laboratorio, mobile) | Prima | Dopo |
|---|---|---|
| First Contentful Paint | 3,2 s | 1,4 s |
| Largest Contentful Paint | 6,4 s | 2,6 s |
| Total Blocking Time | 540 ms | 130 ms |
| Cumulative Layout Shift | 0,31 | 0,001 |
| Speed Index | 5,1 s | 1,4 s |

Il CLS è praticamente azzerato e lo sfarfallio all’apertura delle pagine è scomparso: il contenuto compare già con la forma definitiva. Il tempo di caricamento dell’elemento principale si è più che dimezzato e il thread principale è molto meno occupato. Non è servito un plugin più potente, ma spostare la cache al livello del server e fare poche ottimizzazioni mirate, per modello di pagina.
Come manteniamo il risultato
Il CSS critico va aggiornato quando cambia un modello di pagina, non quando si pubblica un articolo: per questo è legato ai rilasci del tema e verificato a ogni modifica. Le prove in laboratorio sulle pagine principali vengono ripetute a ogni rilascio, e i dati degli utenti reali vengono seguiti nel tempo, sapendo che il Chrome UX Report riflette i miglioramenti con una finestra mobile di 28 giorni.