CDN vs Cache
Una rete di distribuzione dei contenuti (CDN) è un sistema di server distribuiti che forniscono contenuti e pagine web agli utenti in base alla loro posizione geografica per migliorare le prestazioni e ridurre la latenza. Una CDN esegue il caching: la cache è una funzionalità fondamentale di una CDN. Memorizza nella cache e archivia i file essenziali del tuo sito web, come pagine HTML, file JavaScript, file CSS, immagini e video, su server periferici, con conseguente riduzione dei tempi di caricamento.
Cos'è una cache CDN?
Nel contesto delle CDN, il caching della CDN riduce la latenza consentendo di fornire i contenuti da una posizione più vicina all'utente, migliorando significativamente i tempi di caricamento. Funziona memorizzando copie dei contenuti su edge server distribuiti in tutto il mondo. Ogni volta che un utente richiede dei contenuti, la CDN li fornisce dal server edge più vicino, invece di attendere la risposta del server di origine. Ciò riduce il carico di lavoro sul server di origine e supporta un volume di traffico più elevato distribuendo le richieste su più server.
Poiché una CDN è essenzialmente una cache, potresti essere tentato di evitare complicazioni non utilizzando la cache del browser. Tuttavia, ogni cache ha i propri vantaggi che l'altra non offre. In questo post spiegherò i vantaggi di ciascuna e come combinarle per ottenere prestazioni ottimali del sito web e la migliore esperienza per gli utenti finali.
Cos'è il cache busting?
Il cache busting è il processo di caricamento di un nuovo file per sostituire un file già esistente e memorizzato nella cache. Il cache busting è utile perché impedisce al browser di recuperare il vecchio file che si sta sostituendo.
Perché utilizzare la navigazione con cache CDN?
Sebbene le CDN svolgano un ottimo lavoro nel fornire asset molto rapidamente, non possono fare molto per gli utenti che si trovano in zone isolate e hanno a malapena una tacca di ricezione sul proprio telefono. Infatti, secondo i rapporti Cedexis, negli Stati Uniti il 95° percentile del tempo di andata e ritorno (RTT) verso tutti i CDN supera abbondantemente i 200 millisecondi. Ciò significa che almeno il 5% dei tuoi utenti, se non di più, rischia di avere un'esperienza lenta con il tuo sito web o la tua applicazione. Per riferimento, il 50° percentile, o mediana, dell'RTT è di circa 45 millisecondi.
Allora perché utilizzare una CDN? Perché non affidarsi semplicemente alla cache del browser?
Controllo. Con la maggior parte delle CDN, è possibile eliminare gli asset dalla cache, cosa molto utile quando si apportano modifiche agli asset stessi. Con la cache del browser questa opzione non è disponibile.
Le prime impressioni contano. La cache del browser non è di alcun aiuto quando un utente visita il tuo sito per la prima volta, poiché è fredda (vuota di oggetti utili). Le CDN rendono l'esperienza dell'utente con una cache del browser fredda il più veloce possibile, mentre una cache del browser calda renderà le pagine consecutive ancora più veloci.
Le CDN continuano ad avere un vantaggio geografico. Anche se un utente rientra nel 95° percentile, un RTT di 250 millisecondi è comunque migliore di un RTT di 350 millisecondi. Soprattutto se si considera che ogni asset richiede almeno un round trip su una connessione aperta, ma è necessario un round trip aggiuntivo per aprire tale connessione. Il Transport Layer Security (TLS, precedentemente denominato SSL) aggiunge almeno un altro round trip per connessione, a volte anche due. Tutti questi round trip aggiuntivi si accumulano rapidamente.
Le CDN sono molto più efficienti, poiché la loro cache è condivisa tra tutti gli utenti. Ciò significa un carico minore sui server di origine, senza la necessità di un livello di cache proprio nella piattaforma.
Come utilizzare sia la cache CDN che quella del browser
Ora che abbiamo stabilito che una CDN è ancora importante e che anche la cache del browser è piuttosto preziosa, ecco due approcci per combinare le due cose:
Un breve time to live (TTL) per la cache del browser, combinato con TTL lunghi e pulizia sul lato CDN.
Un TTL lungo sia per la CDN che per la cache del browser, ma con cache buster basati sulla versione.
Di seguito, esaminerò nel dettaglio ciascun approccio e discuterò come è possibile utilizzare anche una combinazione dei due.
TTL brevi e lunghi
Idealmente, dovresti utilizzare un TTL per la cache del browser che copra l'intera visita, ma senza eccedere. In questo modo, i tuoi utenti potranno godere di un caricamento veloce delle pagine durante la loro visita, senza ritrovarsi con risorse obsolete quando torneranno in un secondo momento. I tuoi strumenti di analisi dovrebbero essere in grado di indicarti la durata media delle visite al tuo sito, ma in genere 5 o 10 minuti sono un buon valore di riferimento.
Per quanto riguarda Fastly, consiglierei di utilizzare un TTL di un mese o un anno e di impostare la pulizia come parte della pipeline di distribuzione, in modo che Fastly sia in grado di fornire le nuove versioni il prima possibile. Per ulteriori informazioni sulla pulizia, consultare https://docs.fastly.com/guides/purging/.
Ricorda: non eseguire il comando di eliminazione finché non sei sicuro che le nuove versioni degli asset che stai aggiornando siano disponibili sull'origine. Ho assistito a casi in cui qualcuno ha eseguito il comando di eliminazione su Fastly e quest'ultimo ha immediatamente recuperato il file prima che la sincronizzazione con i server di origine fosse completata, causando molta confusione.
Per impostare il TTL della cache del browser, utilizza un'intestazione Cache-Control nella risposta di origine. Successivamente, usa l'intestazione Surrogate-Control o un override nella configurazione Fastly per impostare il TTL.
Ecco un esempio del primo caso:
Cache-Control: max-age=600
Surrogate-Control: max-age=31536000Nell'esempio sopra riportato, l'intestazione Cache-Control indica al browser di memorizzare nella cache per 10 minuti e comunica a Fastly di memorizzarla nella cache per un anno. L'intestazione Surrogate-Control viene rimossa prima che la risposta venga inviata al client, nascondendo questo dettaglio di implementazione agli utenti. Consulta la nostra documentazione per ulteriori informazioni su quali intestazioni è possibile utilizzare per controllare i TTL con Fastly.
Cache buster basati sulla versione
Nonostante il nome, i cache buster possono effettivamente migliorare la memorizzazione nella cache se utilizzati con cautela. Fondamentalmente, un cache buster è un nuovo parametro della stringa di query che viene aggiunto all'URL. Mentre i server web e la maggior parte dei server delle applicazioni ignorano semplicemente i parametri della stringa di query che non li interessano, le cache devono presumere che qualsiasi differenza nella stringa di query influirà sul risultato. Ciò include la cache del browser. I browser devono trattare ciascuno dei seguenti elementi come tre oggetti unici, anche se il server restituisce la stessa identica risposta per tutti:
https://www.example.com/css/main.css, https://www.example.com/css/main.css?cb=foo e https://www.example.com/css/main.css?foo=bar
Supponiamo che la tua app sia al build 133. Invece di collegarsi a https://www.example.com/css/main.css, la tua app si collegherà a https://www.example.com/css/main.css?v=133. Quando passerai al build 134, la tua app si collegherà a https://www.example.com/css/main.css?v=134 . Ora il browser deve recuperare questa nuova versione di main.css, anche se ne possiede ancora una copia non scaduta.
Di solito si usa un hash (breve) del contenuto del file, un numero di build o un hash di commit.
Personalmente preferisco utilizzare un hash del contenuto del file. In questo modo, il cache buster cambia solo quando cambia il contenuto. Con i numeri di build o gli hash di commit, il cache buster cambia ogni volta che cambia qualcosa. Tuttavia, poiché tutti gli URL delle risorse del tuo sito devono avere il cache buster, può essere più facile utilizzare il numero di build o l'hash di commit.
Lo svantaggio di questo approccio è che bisogna aggiornare tutti gli URL degli asset ogni volta che si apporta una modifica. Il vantaggio è che puoi avere i tuoi asset memorizzati nella cache del browser con TTL lunghi e comunque fare in modo che il browser recuperi gli asset aggiornati quando la cache è scaduta.
Combinare e abbinare
Poiché la CDN di Fastly consente di eliminare i contenuti obsoleti entro 150ms, è opportuno prendere in considerazione anche la memorizzazione nella cache di tutte le pagine HTML. Tuttavia, anche se è possibile riprogettare il sito per utilizzare i cache buster per risorse come immagini, fogli di stile e JavaScript, non si dovrebbero mai utilizzare i cache buster sugli URL delle pagine stesse: i motori di ricerca come Google penalizzano la presenza di stringhe di query negli URL delle pagine.
Quindi, quando si memorizzano le pagine nella cache, è opportuno considerare l'utilizzo della tecnica TTL breve e lunga per le pagine e dei cache buster per gli asset utilizzati da tali pagine.
Elementi avanzati: riconvalida
Un effetto collaterale molto positivo dell'utilizzo della cache del browser è che i browser conservano gli oggetti anche se sono scaduti e inviano ulteriori intestazioni di rivalidazione con le loro richieste. Se l'oggetto richiesto non è cambiato, il CDN può semplicemente rispondere con uno stato 304 Not Modified, che non ha alcun corpo, indicando al browser che può utilizzare l'oggetto scaduto e, facoltativamente, fornire un nuovo TTL.
Sebbene ogni richiesta che ottiene una risposta 304 richieda comunque un round trip per essere completata, l'assenza del corpo della risposta comporta un notevole risparmio di larghezza di banda. Questo non solo è un vantaggio per gli utenti con connessioni lente, ma potrebbe anche ridurre i costi mensili del CDN.
Per far funzionare la rivalidazione, è sufficiente assicurarsi che l'origine includa un'intestazione Last-Modifiedo ETag nelle sue risposte. La buona notizia è che la maggior parte dei server web include già intestazioni Last-Modified ed ETag per qualsiasi file statico che servano dal disco. Il valore dell'intestazione Last-Modified si basa sull'ora di modifica del file. Il valore dell'intestazione ETag si basa (in Apache) sull'ora di modifica, sul numero di inode e sulla dimensione.
Quando un browser rileva una di queste due intestazioni, o entrambe, su oggetti scaduti nella propria cache, aggiungerà un'intestazione If-Modified-Since con il valore di Last-Modified e aggiungerà un'intestazione If-None-Match con il valore di ETag. Un oggetto è considerato invariato se i valori di If-None-Match ed ETag sono uguali e se il valore di If-Modified-Since corrisponde o è successivo al valore di Last-Modified.
Se disponi di un unico server web per i tuoi asset statici, probabilmente la rivalidazione funziona già perfettamente grazie alle impostazioni predefinite comuni.
Tuttavia, se si utilizzano più server web per garantire la ridondanza e ciascuno di essi dispone di uno storage locale anziché condiviso, è possibile che la rivalidazione fallisca in modo casuale. Poiché non è possibile garantire che a un determinato file venga assegnato lo stesso numero di inode su ciascun server web, l'intestazione ETag generata per esso sarà diversa da un server all'altro. Inoltre, la maggior parte degli script di distribuzione non conserva l'ora di modifica durante la copia dei file, il che significa che anche l'intestazione Last-Modified sarà diversa.
Ciò è negativo per due motivi. Innanzitutto, quando Fastly comunica con l'origine, potrebbe verificarsi uno spreco di larghezza di banda non necessaria a causa delle risposte complete invece che delle risposte 304. In secondo luogo, Fastly potrebbe finire per avere valori diversi di ETag e Last-Modified su server diversi. Poiché non è garantito che i browser comunichino con lo stesso server per ogni richiesta, potrebbero anche ricevere risposte complete non necessarie a causa di una discrepanza nei valori.
Per sfruttare al meglio la rivalidazione se si dispone di più server web con archiviazione locale, consiglio di disattivare ETag preferendo l'uso esclusivo di Last-Modified e di assicurarsi che lo script di distribuzione conservi l'ora di modifica durante la copia dei file.
Se utilizzi un provider di archiviazione cloud, come Google Cloud Storage o Amazon S3, l'intestazione ETag dovrebbe essere già impostata automaticamente su un hash del contenuto. Ciò rende l'archiviazione cloud una delle origini più ottimali per Fastly, poiché il ricaricamento dello stesso identico file non modifica il suo ETag.
