La prima pagina è spesso anche l’ultima: CSS inline, CSS esterno e Critical CSS

Il CSS esterno conviene grazie alla cache, ma molte visite si fermano alla prima pagina; tutto inline gonfia l’HTML. Il Critical CSS risolve il compromesso: poco CSS subito, il resto dopo.

Una pagina con il primo schermo evidenziato in verde fino a una linea tratteggiata, accanto a un blocco di codice con il CSS critico da 12 KB inline nell’head e il foglio di stile completo caricato con un preload

Prima o poi, in ogni progetto di ottimizzazione, arriva la stessa domanda: il CSS va inserito direttamente nella pagina HTML o caricato da un foglio di stile esterno? La risposta classica è netta: file esterno, scaricato una volta e poi riutilizzato dalla cache per tutte le pagine successive. La prima pagina paga un piccolo costo, le altre diventano più veloci.

È un ragionamento corretto, ma si basa su un presupposto che spesso non corrisponde al comportamento reale degli utenti: che dopo la prima pagina ne arrivi una seconda. Molte visite partono da un risultato di Google, da un post social, da una newsletter o da un link condiviso in chat. L’utente apre la pagina, legge quello che cercava e se ne va. La navigazione successiva, quella in cui la cache avrebbe ripagato il costo iniziale, semplicemente non avviene. Ed è da qui che conviene ripensare il modo in cui consegniamo il CSS.

Il vantaggio del CSS esterno: la cache

Il modo più comune di includere gli stili è un collegamento a un file:

<link rel="stylesheet" href="/css/style.css">

È una soluzione pulita e facile da mantenere. Con le giuste intestazioni di cache il browser conserva il file e lo riutilizza su tutte le pagine che lo richiamano, senza scaricarlo di nuovo. Un unico foglio di stile può contenere le regole di header, menu, articoli, moduli, tabelle e schede prodotto, e ogni modifica si propaga a tutto il sito. Per un sito con centinaia di pagine è un vantaggio concreto.

Perché un CSS esterno rallenta il primo disegno

Il limite del foglio esterno è il suo ruolo nel percorso critico di rendering. Quando il browser legge l’<head> e trova un <link rel="stylesheet">, deve scaricare e analizzare quel file prima di disegnare la pagina: il CSS è una risorsa bloccante. Il motivo è sensato, perché mostrare una pagina senza stile e poi ridisegnarla sarebbe peggio. Ma significa che il primo disegno aspetta un’ulteriore richiesta di rete.

Dalla fibra dell’ufficio questa attesa è impercettibile: qualche decina di millisecondi per un file da 150 KB. Su uno smartphone con una rete 4G mediocre, in una zona di montagna, in un edificio con muri spessi o in una località turistica lontana dalle grandi infrastrutture, la situazione cambia. Non conta solo la banda: conta la latenza, cioè il tempo tra la scoperta della risorsa, la richiesta e l’arrivo dei primi byte. Ogni dipendenza critica in più, in queste condizioni, diventa visibile.

Il pregiudizio della “prima pagina un po’ più lenta”

Il ragionamento tradizionale accetta una prima pagina leggermente più lenta in cambio di pagine successive velocissime. Dal punto di vista tecnico non fa una piega. Diventa sbagliato quando viene scambiato per una descrizione di come si comportano gli utenti. Chi cerca su Google come configurare una funzione, apre l’articolo, trova la risposta e chiude la scheda non visiterà mai la home, la categoria o altri cinque articoli. Lo stesso vale per landing page delle campagne, schede prodotto raggiunte da un comparatore, articoli condivisi sui social e pagine di documentazione.

Per tutte queste visite l’obiettivo non è rendere veloce la navigazione all’interno del sito, ma rendere velocissima la pagina che l’utente ha deciso di aprire adesso. La prima pagina, molto spesso, è anche l’ultima.

E se mettessimo tutto il CSS inline?

La conclusione opposta sembra naturale: se il file esterno aggiunge una richiesta, inseriamo tutto il CSS in un blocco <style> nell’HTML. Le regole arrivano insieme al documento e non c’è nulla da aspettare. Con pochi kilobyte funziona benissimo. Con un foglio di stile moderno, no.

Su WordPress, WooCommerce, Magento o PrestaShop, specie con temi multiuso e page builder, il CSS supera facilmente i 150 o 200 KB. Inserito in ogni pagina, trasforma un documento HTML da 60 KB in uno da 200 o 300 KB. E l’HTML è la risorsa più preziosa del caricamento: finché non arriva e non viene analizzato, il browser non scopre immagini, font, script e preload. Gonfiarlo significa ritardare tutto ciò che viene dopo. In più, quelle stesse regole vengono trasferite di nuovo in ogni pagina: il CSS inline non può essere messo in cache come risorsa autonoma e condivisa.

Tre modi di consegnare il CSS alla prima visita: con il CSS esterno bloccante il browser scarica l’HTML da 60 KB e poi aspetta il foglio di stile da 150 KB prima del primo disegno; con tutto il CSS inline l’HTML pesa 210 KB e il primo disegno arriva dopo il suo download; con il Critical CSS inline l’HTML pesa 72 KB, il primo disegno arriva subito e il resto del CSS si scarica dopo senza bloccare
Esterno bloccante, tutto inline, Critical CSS: cambia il momento del primo disegno.

Entrambi hanno ragione, entrambi hanno torto

Il CSS esterno offre riusabilità, cache indipendente dall’HTML, manutenzione semplice e documenti leggeri, ma aggiunge una dipendenza bloccante proprio al primo caricamento. Il CSS inline elimina quella dipendenza, ma se è troppo gonfia l’HTML, ripete le stesse regole su ogni pagina, rinuncia alla cache e complica la gestione del codice. Come spesso accade nelle performance, la soluzione non sta in uno dei due estremi.

La soluzione: il Critical CSS

Il Critical CSS parte da una domanda semplice: quanto CSS serve davvero per mostrare ciò che l’utente vede appena apre la pagina? Non quello del footer seimila pixel più in basso, non quello della finestra modale che forse verrà aperta, non quello del checkout mentre si legge un articolo. Solo quello necessario al primo schermo, il contenuto “above the fold”.

Una pagina su desktop e la stessa su smartphone con la linea di fine del primo schermo: la parte superiore, con header, titolo, pulsante e immagine principale, è evidenziata come CSS critico da inserire inline nell’HTML; il resto della pagina usa il CSS esterno conservato in cache; su smartphone il primo schermo contiene elementi diversi
Il primo schermo cambia tra desktop e smartphone, e con lui il CSS critico.

Quella piccola quantità di regole va inline nell’<head>, così il browser ha subito tutto ciò che gli serve per disegnare la parte iniziale della pagina. Il resto del CSS continua a vivere in un file esterno, condiviso e in cache, e viene caricato senza bloccare il primo disegno. Una tecnica diffusa è questa:

<head>
	<style>
		/* CSS critico: header, titolo, hero del primo schermo */
		.site-header { height: 80px; background: #fff; }
		.hero { max-width: 1200px; margin: 0 auto; }
		.article-title { font-size: 42px; line-height: 1.1; }
	</style>

	<link rel="preload" href="/css/style.min.css" as="style"
	      onload="this.onload=null;this.rel='stylesheet'">
	<noscript><link rel="stylesheet" href="/css/style.min.css"></noscript>
</head>

Non è una ricetta da applicare alla cieca: il caricamento asincrono dei fogli di stile va progettato e verificato, perché ha implicazioni sulla Content Security Policy, sulla priorità delle risorse e sul rischio di vedere per un istante contenuti senza stile. Ma il principio resta valido: rendere disponibile subito ciò che serve subito, e rimandare ciò che servirà dopo.

Critical CSS non vuol dire “le prime righe del foglio”

Un errore frequente è pensare che basti prendere le prime duecento righe del foglio di stile. Il CSS critico dipende da che cosa compare davvero nel primo schermo, e cambia da un modello di pagina all’altro: una home ha bisogno degli stili dell’hero, un articolo di titolo, autore e immagine in evidenza, una scheda prodotto di galleria, prezzo, disponibilità e pulsante d’acquisto. Cambia anche con il dispositivo, perché ciò che sta nel primo schermo di un monitor non coincide con quello di uno smartphone largo 390 pixel.

Per questo il Critical CSS va generato in modo automatico, nel processo di build o di ottimizzazione, per ciascun modello di pagina e per le larghezze principali, e rigenerato quando cambiano template e stili. Mantenerlo a mano riga per riga porta rapidamente a regole mancanti o superate.

Il Critical CSS non deve diventare un altro mostro inline

C’è una trappola in cui cadono molti strumenti automatici: inserire “per sicurezza” quantità enormi di CSS nel blocco critico. Se il CSS inline arriva a 100 o 150 KB si è perso quasi tutto il vantaggio, e si ricade nei problemi del CSS interamente inline. Lo scopo è il contrario: il minimo indispensabile per disegnare correttamente il primo contenuto significativo, di solito pochi kilobyte, con tutto il resto fuori dal percorso critico.

Il confronto sui byte trasferiti chiarisce il compromesso. In una visita di tre pagine, il CSS tutto inline viene trasferito tre volte; con il Critical CSS la prima pagina scarica il blocco critico più il foglio completo, le successive solo il blocco critico, perché il foglio è in cache.

Byte trasferiti in una visita di tre pagine, esempio illustrativo con HTML da 60 KB, CSS completo da 150 KB e CSS critico da 12 KB: con tutto il CSS inline ogni pagina pesa 210 KB, per un totale di 630 KB; con il Critical CSS e il file in cache la prima pagina pesa 222 KB e le successive 72 KB, per un totale di 366 KB
Esempio illustrativo: il Critical CSS vince sulla navigazione e, grazie al foglio non bloccante, anche sulla prima pagina.

Testare come un utente con una rete mediocre

È probabilmente il consiglio più importante. Chi sviluppa collegato a una fibra da centinaia di megabit non dovrebbe usare la propria esperienza come termine di paragone. Nei DevTools di Chrome si possono simulare latenza alta, banda ridotta e processori meno potenti: è in queste condizioni che il percorso critico diventa evidente, e che un foglio di stile che dalla scrivania arriva all’istante si rivela il motivo di centinaia di millisecondi di schermo bianco. Il pannello Coverage mostra quanta parte del CSS serve davvero al primo schermo, e il pannello Performance quando avviene il primo disegno.

Il riscontro definitivo, come sempre, arriva dai dati degli utenti reali: First Contentful Paint e LCP al 75° percentile, soprattutto da mobile. E attenzione a non confondere il Critical CSS con la rimozione automatica del CSS “inutilizzato”, che fotografa la pagina in un solo stato e può eliminare regole che servono dopo, come abbiamo spiegato parlando di CSS inutilizzato e stati dinamici: il foglio completo, qui, arriva sempre.

La domanda giusta

“CSS inline o CSS esterno?” è una domanda troppo semplice per un problema che riguarda priorità e tempi. La domanda corretta è: quale CSS serve adesso, e quale può arrivare dopo? Quello che serve subito deve essere piccolo, mirato e disponibile senza dipendenze critiche. Quello globale e meno urgente può restare esterno, beneficiare della cache e servire il resto della pagina e della navigazione.

In sintesi

Il modello classico, prima pagina un po’ più lenta e poi navigazione velocissima grazie alla cache, è tecnicamente valido ma descrive male molte visite reali, in cui la prima pagina è anche l’ultima. Mettere tutto il CSS inline non è la risposta: gonfia l’HTML, ripete gli stessi byte e rinuncia alla cache. Il Critical CSS è il compromesso intelligente: pochissimo CSS inline per disegnare subito il primo schermo, un foglio esterno non bloccante per tutto il resto.

Non si tratta tanto di scaricare meno, quanto di non aspettare ciò che non serve ancora. L’utente non giudica il sito dalla velocità teorica della quinta pagina: lo giudica nel momento in cui tocca un risultato di ricerca e aspetta che sullo schermo compaia qualcosa. E in quel momento c’è una sola occasione per sembrare veloci: esserlo subito.

IL PROSSIMO PASSO

Partiamo
dal tuo sito.

Raccontaci il progetto, i problemi che riscontri e i tuoi obiettivi. Definiremo insieme un intervento su misura.

Richiedi un’analisi

Ti porta al modulo della pagina Contatti.

MANAGED SERVER S.R.L.info@corewebvitals.it +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Preferisci un modulo online?
Contattaci su managedserver.it ↗