Performance
stale-while-revalidate: come si configura e come si testa
Cosa fa davvero `stale-while-revalidate`, come si combina con `stale-if-error` e come verificare che il CDN stia servendo la versione vecchia mentre aggiorna quella nuova.
In sintesi
- `stale-while-revalidate` serve la copia vecchia e aggiorna in background: l’utente non aspetta.
- Non è una cache infinita: la finestra dichiarata è il tempo massimo in cui accetti la copia vecchia.
- Non usarlo su risposte personalizzate, mutazioni o dati che devono essere esatti al secondo.
`stale-while-revalidate` (SWR) è una direttiva di `Cache-Control`: per N secondi dopo la scadenza, la copia vecchia può essere servita mentre una richiesta in background la aggiorna. L’utente vede subito qualcosa, il CDN lavora dopo.
La sintassi
Cache-Control: public, max-age=60, stale-while-revalidate=300
Significato: per 60 secondi la risposta è fresca; dal secondo 61 al 360 può essere servita la copia vecchia, mentre il CDN la rigenera. Dopo, la richiesta aspetta una risposta nuova.
SWR e stale-if-error non sono la stessa cosa
| Direttiva | Quando interviene | Cosa rischia |
|---|---|---|
| stale-while-revalidate | Dopo la scadenza, con backend raggiungibile | Dati vecchi per la durata della finestra |
| stale-if-error | Quando il backend restituisce errore | Mostrare dati vecchi durante un guasto |
| max-age | Prima della scadenza | Nessuno: è la finestra fresca |
| no-store | Sempre | Perdere ogni vantaggio della cache |
Combinali solo se sai cosa stai promettendo: `max-age=60, stale-while-revalidate=300, stale-if-error=600` significa che un errore può prolungare la vita dei dati vecchi.
Dove ha senso
- Liste di catalogo che cambiano lentamente.
- Immagini e asset con URL versionati.
- Risposte pubbliche e identiche per tutti.
- Pagine marketing senza dati personali.
Dove non ha senso
- Risposte con dati dell’utente o token.
- Mutazioni e endpoint che cambiano stato.
- Saldi o prezzi che devono essere esatti al minuto.
- Risposte che dipendono da cookie o geolocalizzazione.
Come si testa
Non fidarti dell’header: guarda cosa risponde il bordo. Due richieste ravvicinate devono mostrare la stessa versione; dopo la finestra, la seconda può ancora mostrare la vecchia mentre il CDN rigenera.
curl -sI https://example.com/api/catalog | grep -i "cache-control\|age\|x-cache"
curl -sI https://example.com/api/catalog | grep -i "age\|x-cache"
Controlla `Age` e l’header del provider (`x-cache`, `cf-cache-status`). Se `Age` non cresce, il CDN non sta servendo dalla cache e la direttiva è solo decorativa.
Il caso reale del catalogo
Le liste pubbliche di EneUI usano una cache breve con finestra stale: il catalogo è pubblico, identico per tutti e cambia con i cicli di raccolta. Con 111.985 componenti (31 ottobre 2026) servire dalla cache non è un dettaglio: è ciò che tiene in piedi il sito su una macchina piccola.
Domande frequenti
SWR aggiorna la cache in background?
Sì, quando una richiesta arriva dopo la scadenza: serve la copia vecchia e avvia il refresh. Non c’è un job separato.
Posso usarlo su un’API con login?
No, se la risposta è personalizzata e il CDN è condiviso. Servire la risposta di un utente a un altro è un incidente, non un bug di performance.
Quanto deve durare la finestra?
Quanto il prodotto tollera dati vecchi. Non esiste un numero universale: dichiara la tolleranza e configura di conseguenza.
SWR vale anche per le immagini?
Sì, spesso tramite la CDN. Gli asset con URL versionati sono il caso più sicuro, perché il contenuto non cambia mai sotto lo stesso URL.
Come verifico che funzioni su Vercel o Cloudflare?
Guarda gli header di stato cache del provider e l’header `Age`. Se non compaiono, la direttiva non è stata applicata a quel percorso.