Mantenimento degli aggiornamenti con lo stale-while-revalidate

Uno strumento aggiuntivo per aiutarti a bilanciare l'immediatezza e l'aggiornamento quando pubblichi la tua app web.

stale-while-revalidate aiuta gli sviluppatori a trovare il giusto equilibrio tra immediatezza (caricamento immediato dei contenuti memorizzati nella cache) e aggiornamento (garanzia che gli aggiornamenti dei contenuti memorizzati nella cache vengano utilizzati in futuro). Se gestisci una libreria o un servizio web di terze parti che si aggiorna con una frequenza regolare o se le risorse proprietarie tendono ad avere una durata breve, stale-while-revalidate potrebbe essere un'aggiunta utile ai tuoi criteri di memorizzazione nella cache esistenti.

Il supporto per l'impostazione di stale-while-revalidate insieme a max-age nell'intestazione della risposta Cache-Control è disponibile in Chrome 75 e Firefox 68.

I browser che non supportano stale-while-revalidate ignoreranno automaticamente il valore di configurazione e utilizzeranno max-age, come spiegherò a breve...

Che cosa significa?

Suddividiamo stale-while-revalidate in due parti: l'idea che una risposta memorizzata nella cache potrebbe essere obsoleta e la procedura di convalida.

Innanzitutto, come fa il browser a sapere se una risposta memorizzata nella cache è "inutilizzabile"? Un'intestazione di risposta Cache-Control che contiene stale-while-revalidate deve contenere anche max-age e il numero di secondi specificato tramite max-age è ciò che determina l'obsolescenza. Qualsiasi risposta memorizzata nella cache più recente di max-age viene considerata aggiornata, mentre le risposte memorizzate nella cache precedenti sono obsolete.

Se la risposta memorizzata nella cache locale è ancora aggiornata, può essere utilizzata così com'è per soddisfare la richiesta di un browser. Dal punto di vista di stale-while-revalidate, non c'è nulla da fare in questo scenario.

Tuttavia, se la risposta memorizzata nella cache non è aggiornata, viene eseguito un altro controllo in base alla data di creazione: la data di creazione della risposta memorizzata nella cache rientra nella finestra di tempo aggiuntiva fornita dall'impostazione stale-while-revalidate?

Se la data di una risposta non aggiornata rientra in questo intervallo, verrà utilizzata per soddisfare la richiesta del browser. Allo stesso tempo, verrà inviata una richiesta di "convalida" alla rete in modo da non ritardare l'utilizzo della risposta memorizzata nella cache. La risposta restituita potrebbe contenere le stesse informazioni della risposta memorizzata nella cache in precedenza o essere diversa. In ogni caso, la risposta della rete viene memorizzata localmente, sostituendo qualsiasi elemento precedentemente memorizzato nella cache e reimpostando il timer "aggiornamento" utilizzato durante i futuri confronti max-age.

Tuttavia, se la risposta in cache non aggiornata è abbastanza vecchia da non rientrare nel periodo di tempo stale-while-revalidate, non soddisferà la richiesta del browser. Il browser recupererà invece una risposta dalla rete e la utilizzerà sia per soddisfare la richiesta iniziale sia per compilare la cache locale con una risposta aggiornata.

Esempio dal vivo

Di seguito è riportato un semplice esempio di API HTTP per restituire l'ora corrente, più specificamente il numero corrente di minuti dopo l'ora.

In questo scenario, il server web utilizza questa intestazione Cache-Control nella risposta HTTP:

Cache-Control: max-age=1, stale-while-revalidate=59

Questa impostazione significa che, se una richiesta dell'ora viene ripetuta entro il prossimo 1 secondo, il valore memorizzato nella cache in precedenza sarà ancora aggiornato e utilizzato così com'è, senza nessuna convalida.

Se una richiesta viene ripetuta tra 1 e 60 secondi dopo, il valore memorizzato nella cache sarà inattivo, ma verrà utilizzato per soddisfare la richiesta API. Allo stesso tempo, "in background", verrà inviata una richiesta di convalida per compilare la cache con un valore aggiornato da utilizzare in futuro.

Se una richiesta viene ripetuta dopo più di 60 secondi, la risposta obsoleta non viene utilizzata e sia la soddisfazione della richiesta del browser sia la convalida della cache dipendono dalla ricezione di una risposta dalla rete.

Ecco una suddivisione di questi tre stati distinti, insieme al periodo di tempo in cui ciascuno di essi si applica per il nostro esempio:

Un diagramma che illustra le informazioni della sezione precedente.

Quali sono i casi d'uso comuni?

Sebbene l'esempio riportato sopra per un servizio API "minuti dopo l'ora" sia artificioso, illustra il caso d'uso previsto: servizi che forniscono informazioni che devono essere aggiornate, ma in cui è accettabile un certo grado di inattualità.

Esempi meno artificiosi potrebbero essere un'API per le condizioni meteorologiche attuali o i titoli delle notizie principali scritti nell'ultima ora.

In genere, qualsiasi risposta che si aggiorna a un intervallo noto, è probabile che venga richiesta più volte ed è statica all'interno di quell'intervallo è un buon candidato per la memorizzazione nella cache a breve termine tramite max-age. L'utilizzo di stale-while-revalidate oltre a max-age aumenta la probabilità che le richieste future possano essere soddisfatte dalla cache con contenuti più recenti, senza bloccare una risposta di rete.

Come interagisce con i service worker?

Se hai sentito parlare di stale-while-revalidate, è probabile che fosse nel contesto delle ricette utilizzate all'interno di un service worker.

L'utilizzo di stale-Mentre-convalida tramite un'intestazione Cache-Control condivide alcune somiglianze con il suo utilizzo in un service worker e si applicano molte delle stesse considerazioni sui compromessi di aggiornamento e sulla durata massima. Tuttavia, esistono alcune considerazioni da tenere in considerazione quando decidi se implementare un approccio basato su service worker o semplicemente affidarti alla configurazione dell'intestazione Cache-Control.

Utilizza un approccio con service worker se…

  • Stai già utilizzando un service worker nella tua applicazione web.
  • Hai bisogno di un controllo granulare sui contenuti delle tue cache e vuoi implementare qualcosa di simile a un criterio di scadenza per l'elemento meno di recente utilizzato. Il modulo Scadenza della cache di Workbox può aiutarti a risolvere questo problema.
  • Vuoi ricevere una notifica quando una risposta non aggiornata cambia in background durante il passaggio di convalida. Il modulo Aggiornamento cache di trasmissione di Workbox può essere utile in questo caso.
  • Questo comportamento stale-while-revalidate è necessario in tutti i browser moderni.

Utilizza un approccio Cache-Control se…

  • Preferiresti non gestire l'overhead associato al deployment e alla gestione di un service worker per la tua applicazione web.
  • Puoi consentire alla gestione automatica della cache del browser di impedire che le cache locali diventino troppo grandi.
  • Non c'è problema con un approccio attualmente non supportato in tutti i browser moderni (da luglio 2019; il supporto potrebbe aumentare in futuro).

Se utilizzi un worker di servizio e hai attivato stale-while-revalidate anche per alcune risposte tramite un'intestazione Cache-Control, in genere il worker di servizio avrà la "prima possibilità" di rispondere a una richiesta. Se il servizio worker decide di non rispondere o se durante la generazione di una risposta effettua una richiesta di rete utilizzando fetch(), il comportamento configurato tramite l'intestazione Cache-Control verrà applicato.

Scopri di più

Immagine hero di Samuel Zeller.