Cache HTTP spiegata bene: Cache-Control, ETag e il rischio dei contenuti sbagliati 🚀📦

Schermata di terminale con informazioni di sistema in rosso su sfondo nero

La cache è uno degli strumenti più efficaci per velocizzare un sito. Ma quando viene configurata male può creare problemi strani: un utente vede una pagina non aggiornata, un carrello mostra informazioni incoerenti oppure una modifica sembra non comparire mai, neanche dopo aver svuotato la cache del browser. 🚀

Per capire cosa succede conviene partire da un concetto spesso trascurato: non esiste una sola cache. Ci sono quella del browser, quella del server, quella dei plugin e quella delle CDN. A coordinarne una parte intervengono gli header HTTP.

Che cos’è la cache HTTP?

Quando il browser richiede una risorsa, come un’immagine, un foglio CSS o una pagina HTML, può ricevere indicazioni su come conservarla e quando verificarne nuovamente la validità. Queste indicazioni sono trasmesse attraverso header della risposta.

La cache può evitare download ripetuti e ridurre il lavoro del server. Tuttavia le regole corrette per un’immagine statica non sono necessariamente quelle giuste per una pagina che mostra dati personalizzati.

Cache-Control: l’header che definisce le regole 📦

Uno degli header più importanti è Cache-Control. Può indicare per quanto tempo una risposta è considerata fresca e quali tipi di cache possono conservarla.

Per esempio:

Cache-Control: public, max-age=3600

Questa direttiva consente la memorizzazione in cache e indica una durata di freschezza di un’ora. Non significa che il contenuto sarà necessariamente cancellato dopo 3600 secondi: significa che, trascorso quel periodo, una cache che vuole riutilizzarlo deve applicare le regole di rivalidazione previste.

Un altro esempio:

Cache-Control: private, no-cache

private impedisce la memorizzazione nelle cache condivise, mentre no-cache richiede la rivalidazione prima del riutilizzo. Il nome può trarre in inganno: no-cache non significa “non memorizzare mai”. Per i casi in cui è necessario evitare la memorizzazione, la direttiva pertinente è no-store.

ETag: chiedere se il contenuto è cambiato 🔎

Un server può associare alla risposta un identificatore chiamato ETag. Quando la risorsa diventa da rivalidare, il browser può inviare una richiesta condizionale con If-None-Match, riportando l’identificatore che possiede.

Se il contenuto non è cambiato secondo il validatore, il server può rispondere con 304 Not Modified, evitando di trasferire nuovamente il corpo della risorsa.

È un meccanismo molto utile per risparmiare banda. Ma richiede che server, proxy e CDN gestiscano coerentemente i validatori, soprattutto quando comprimono o trasformano i contenuti.

Last-Modified e le richieste condizionali

Un altro approccio usa l’header Last-Modified, che comunica una data di modifica. Il client può successivamente inviare If-Modified-Since per chiedere se la risorsa è cambiata.

Non è sempre preciso quanto un validatore basato sul contenuto, ma rimane utile in numerosi scenari. ETag e Last-Modified possono coesistere; non occorre scegliere per forza un solo meccanismo.

Le risorse statiche meritano regole diverse 🖼️

Un’immagine WebP, un file JavaScript versionato o un foglio CSS con nome contenente un hash possono spesso essere conservati a lungo. Se il nome cambia a ogni modifica del contenuto, il browser può distinguere senza ambiguità la nuova versione da quella vecchia.

Un esempio tipico per risorse davvero versionate è:

Cache-Control: public, max-age=31536000, immutable

Non lo applicherei indiscriminatamente a file che mantengono lo stesso URL anche dopo un aggiornamento. In quel caso si rischia di distribuire contenuti obsoleti per molto tempo.

WordPress, utenti autenticati e WooCommerce 🛒

Su un blog pubblico, memorizzare le pagine HTML può portare grandi benefici. Ma WordPress non serve soltanto pagine uguali per tutti: ci sono aree riservate, sessioni, form, anteprime, carrelli e checkout.

Questi contenuti richiedono regole specifiche. Una cache condivisa che memorizza risposte personalizzate senza distinguerle correttamente può provocare errori funzionali e, nei casi peggiori, esposizione di informazioni tra utenti.

Per questo non considero mai una configurazione “ottimale” soltanto perché migliora il punteggio di PageSpeed Insights. La velocità è importante, ma prima viene la correttezza del contenuto mostrato.

Come distinguere browser, CDN e cache del server ☁️

Quando una modifica non appare, cerco di capire quale livello stia servendo la risposta. Controllo gli header HTTP, l’eventuale indicazione di cache hit/miss fornita dal provider e il comportamento tra utente autenticato e visitatore anonimo.

Per esempio, un test iniziale può essere:

curl -I "https://esempio.it/pagina/"

Osservo Cache-Control, ETag, Last-Modified, Age e gli eventuali header diagnostici del sistema di caching. Non tutti saranno presenti: dipende dall’architettura.

Se utilizzo WordPress con una cache applicativa e una CDN, verifico separatamente i due livelli. Svuotare la cache del plugin non garantisce che una copia conservata altrove venga invalidata nello stesso momento.

Tre errori che incontro spesso ⚠️

  1. Confondere no-cache e no-store: sono direttive con significati differenti.
  2. Applicare cache pubblica a risposte personalizzate: non tutte le pagine possono essere condivise tra visitatori.
  3. Impostare durate lunghissime senza versionare le risorse: gli aggiornamenti possono diventare invisibili agli utenti.

La checklist che userei prima di ottimizzare un sito ✅

  • Identificare tutti i livelli di cache presenti.
  • Separare risorse statiche, pagine pubbliche e contenuti personalizzati.
  • Verificare il comportamento per utenti autenticati e anonimi.
  • Controllare carrello, checkout, login e moduli dinamici.
  • Usare nomi versionati per asset con cache di lunga durata.
  • Testare invalidazione e aggiornamento dei contenuti.
  • Misurare prestazioni e correttezza, non soltanto il punteggio sintetico.

Una cache ben progettata è quasi invisibile: il sito risponde più velocemente, ma mostra sempre il contenuto giusto. Per approfondire direttive e semantica degli header, consiglio la guida alla cache HTTP di MDN. 📚

Vuoi aggiungere qualcosa?

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *