Performance

Cache e CDN: hit rate reale, misurato

Su 60 richieste al sito 40 sono state servite dal bordo (66,7%): gli asset statici fanno HIT 40 volte su 40, l'HTML 0 su 20. Il TTFB passa da 26 a 276 ms. Come si misura.

In sintesi

  • Su 60 richieste misurate 40 arrivano dalla cache edge: 66,7% complessivo, 100% sugli asset statici.
  • L'HTML risponde DYNAMIC con Cache-Control: no-cache su tutte le 20 richieste.
  • Il TTFB mediano è 26-34 ms per gli asset e 256-276 ms per l'HTML: la differenza è l'origine.
  • La query string entra nella chiave di cache: una URL nuova fa MISS, la seconda richiesta fa HIT.

Su 60 richieste misurate al sito 40 sono state servite dalla cache edge, il 66,7%: tutte le 40 statiche hanno fatto HIT, tutte le 20 di HTML hanno fatto DYNAMIC. Il TTFB mediano passa da 26-34 ms per gli asset a 256-276 ms per l'HTML.

Cosa risponde il bordo

RisorsaRichiesteHITTTFB medianoCache-Control
Home HTML100276 msno-cache
Articolo HTML100256 msno-cache
CSS101026 msmax-age=2592000, swr=604800
Font101034 msmax-age=31536000, immutable
Immagine101030 msmax-age=2592000
Icona101029 msmax-age=2592000

La differenza tra 30 e 276 ms è il costo dell'origine: l'HTML viene generato a ogni richiesta, gli asset arrivano dal bordo. Non è un difetto della CDN, è una decisione: l'HTML cambia spesso e non ha una chiave di cache stabile.

Misurarlo da terminale

for u in / /blog/core-web-vitals-ttfb /css/components-ui.css \
         /fonts/inter-400-latin.woff2; do
  printf '%s ' "$u"
  curl -sI "https://ui.eneawork.it$u" |
    grep -i -E '^(cf-cache-status|age|cache-control):' | tr '\n' ' '
  echo
done

Il comando stampa stato della cache, età dell'oggetto e politica di cache per ogni URL. Age dice da quanti secondi il bordo ha quella copia: 83.580 s per il CSS, cioè quasi un giorno.

La query string entra nella chiave

Con una URL nuova (?probe=...) la prima risposta è MISS e la seconda è HIT: il parametro fa parte della chiave. Un identificatore di campagna diverso per utente azzera la cache su ogni visita, e lo stesso vale per un parametro di ordinamento nei link interni.

Cosa cambiare

  • Asset con hash nel nome: cache di un anno e immutable, come il font che risponde con max-age=31536000. Fonte: web.dev, CC BY 4.0.
  • HTML: se non puoi metterlo in cache, riduci il TTFB dell'origine. Nel test locale la home risponde in 205 ms. Fonte: web.dev, CC BY 4.0.
  • Query string: normalizza i parametri che non cambiano il contenuto, altrimenti ogni variante è un oggetto nuovo. Fonte: MDN, CC BY-SA 2.5.
  • stale-while-revalidate=604800 serve subito la copia vecchia e la aggiorna dopo: è già attivo sui CSS del sito.

Il limite da dichiarare

La misura viene da un solo client e da un solo punto di presenza (Milano, dal CF-RAY), con dieci richieste per URL. L'hit rate reale dipende dal traffico, dalla distribuzione geografica e dai TTL: un sito con molte pagine HTML e pochi asset mostra una percentuale molto più bassa, perché il 66,7% qui mescola due popolazioni diverse.

Dove continuare

Il catalogo EneUI indicizza 111.985 componenti, per esempio card-stack, e la griglia di 1.556 blocchi: ogni record è una pagina HTML che non finisce in cache edge. Leggi come si misura il TTFB, la cache con un service worker e come si fissa un performance budget.

Domande frequenti

Che cos'è il cache hit rate?

È la percentuale di richieste servite dalla cache invece che dall'origine. Nel nostro campione è 66,7% complessivo e 100% sui soli asset statici.

Perché l'HTML non viene messo in cache?

Perché risponde con Cache-Control: no-cache e cf-cache-status DYNAMIC. Il contenuto cambia spesso e il bordo non ha una chiave stabile per riusarlo.

Come si legge cf-cache-status?

HIT vuol dire servito dal bordo, MISS vuol dire richiesta all'origine con salvataggio, DYNAMIC vuol dire non cacheabile con le regole attuali, EXPIRED vuol dire copia scaduta.

Il TTFB di un HIT è sempre basso?

Dipende dalla distanza dal punto di presenza. Qui 26-34 ms dal bordo contro 256-276 ms dall'origine, misurati dallo stesso client.

La query string rompe la cache?

Sì, se fa parte della chiave. Una URL con un parametro nuovo è un oggetto nuovo: la prima richiesta è MISS, la seconda HIT.