Cache back-forward

La cache back-forward (o bfcache) è un'ottimizzazione del browser che consente di navigare avanti e indietro istantaneamente. Migliora notevolmente l'esperienza di navigazione, soprattutto per gli utenti con reti o dispositivi più lenti.

In qualità di sviluppatori web, è fondamentale capire come ottimizzare le pagine per la bfcache, in modo che gli utenti possano trarre vantaggio da questa funzionalità.

Compatibilità del browser

Tutti i principali browser includono una cache bf, tra cui Chrome dalla versione 96, Firefox e Safari.

Nozioni di base su bfcache

Con la cache di navigazione (bfcache), invece di distruggere una pagina quando l'utente esce, rimandiamo la distruzione e mettiamo in pausa l'esecuzione di JS. Se l'utente torna indietro poco dopo, rendiamo di nuovo visibile la pagina e riattiviamo l'esecuzione di JS. Ciò si traduce in una navigazione nelle pagine quasi istantanea per l'utente.

Quante volte hai visitato un sito web e fatto clic su un link per passare a un'altra pagina, solo per renderti conto che non era quello che volevi e fare clic sul pulsante Indietro? In quel momento, la cache bfcache può fare una grande differenza nella velocità di caricamento della pagina precedente:

Senza bfcache abilitata Viene avviata una nuova richiesta per caricare la pagina precedente e, a seconda di quanto questa pagina sia stata ottimizzata per le visite ripetute, il browser potrebbe dover scaricare di nuovo, analizzare di nuovo ed eseguire di nuovo alcune (o tutte) le risorse appena scaricate.
Con la cache bf attivata Il caricamento della pagina precedente è essenzialmente istantaneo, perché l'intera pagina può essere ripristinata dalla memoria, senza dover accedere alla rete.

Guarda questo video di bfcache in azione per capire la velocità che può apportare alle navigazioni:

L'utilizzo della cache bfcache consente di caricare le pagine molto più rapidamente durante la navigazione avanti e indietro.

Nel video, l'esempio con bfcache è molto più veloce dell'esempio senza.

bfcache non solo accelera la navigazione, ma riduce anche l'utilizzo dei dati, poiché le risorse non devono essere scaricate di nuovo.

I dati sull'utilizzo di Chrome mostrano che 1 navigazione su 10 su computer e 1 su 5 su dispositivo mobile è costituita da un movimento Indietro o Avanti. Con la cache bf attivata, i browser potrebbero eliminare il trasferimento di dati e il tempo di caricamento per miliardi di pagine web ogni giorno.

Come funziona la "cache"

La "cache" utilizzata da bfcache è diversa dalla cache HTTP, che svolge il proprio ruolo nell'accelerare le navigazioni ripetute. bfcache è un'istantanea dell'intera pagina in memoria, incluso l'heap JavaScript, mentre la cache HTTP contiene solo le risposte per le richieste effettuate in precedenza. Poiché è molto raro che tutte le richieste necessarie per caricare una pagina vengano soddisfatte dalla cache HTTP, le visite ripetute che utilizzano i ripristini della cache bfcache sono sempre più veloci anche delle navigazioni non bfcache più ottimizzate.

Bloccare una pagina per riattivarla potenzialmente in un secondo momento richiede una certa complessità in termini di come conservare il codice in corso. Ad esempio, come gestisci le chiamate setTimeout() in cui viene raggiunto il timeout mentre la pagina è nella bfcache?

La risposta è che i browser mettono in pausa eventuali timer in sospeso o promesse non risolte per le pagine in bfcache, incluse quasi tutte le attività in sospeso nelle code di attività JavaScript, e riprendono le attività di elaborazione se la pagina viene ripristinata dalla bfcache.

In alcuni casi, ad esempio per timeout e promesse, questo è un rischio piuttosto basso, ma in altri casi può portare a comportamenti confusi o imprevisti. Ad esempio, se il browser mette in pausa un'attività richiesta nell'ambito di una transazione IndexedDB, può influire su altre schede aperte nella stessa origine, perché è possibile accedere agli stessi database IndexedDB da più schede contemporaneamente. Di conseguenza, in genere i browser non tentano di memorizzare nella cache le pagine nel mezzo di una transazione IndexedDB o durante l'utilizzo di API che potrebbero influire su altre pagine.

Per ulteriori dettagli su come l'utilizzo di varie API influisce sull'idoneità alla cache bfcache di una pagina, consulta Ottimizzare le pagine per la cache bfcache.

La cache bfcache e gli iframe

Se una pagina contiene iframe incorporati, questi ultimi non sono idonei per la cache bfcache. Ad esempio, se vai a un'altra pagina all'interno di un iframe, ma poi torni indietro, il browser tornerà "indietro" all'interno dell'iframe anziché nel frame principale, ma la navigazione a ritroso all'interno dell'iframe non utilizzerà la bfcache.

Anche il frame principale può essere bloccato dall'utilizzo della cache bf se un iframe incorporato utilizza API che lo bloccano. Per evitare questo problema, puoi utilizzare il criterio di autorizzazione impostato nel frame principale o l'uso degli attributi sandbox.

La cache bfcache e le app a pagina singola (SPA)

Poiché bfcache funziona con le navigazioni gestite dal browser, non funziona per le "navigazioni soft" all'interno di un'app a pagina singola (APS). Tuttavia, bfcache può essere utile anche per tornare a un'app SPA anziché eseguire nuovamente un'inizializzazione completa dell'app dall'inizio.

API per osservare bfcache

Anche se bfcache è un'ottimizzazione eseguita automaticamente dai browser, è comunque importante che gli sviluppatori sappiano quando si verifica per poter ottimizzare le pagine e modificare le metriche o la misurazione del rendimento di conseguenza.

Gli eventi principali utilizzati per osservare bfcache sono gli eventi di transizione delle pagine pageshow e pagehide, supportati dalla maggior parte dei browser.

Gli eventi del ciclo di vita della pagina più recenti (freeze e resume) vengono inviati anche quando le pagine entrano o escono dalla bfcache, nonché in alcune altre situazioni, ad esempio quando una scheda in background viene bloccata per ridurre al minimo l'utilizzo della CPU. Questi eventi sono supportati solo nei browser basati su Chromium.

Osserva quando una pagina viene ripristinata da bfcache

L'evento pageshow viene attivato subito dopo l'evento load quando la pagina viene caricata inizialmente e ogni volta che la pagina viene ripristinata da bfcache. L'evento pageshow ha una proprietà persisted, che è true se la pagina è stata ripristinata da bfcache e false in caso contrario. Puoi utilizzare la proprietà persisted per distinguere i caricamenti di pagine regolari dai ripristini della cache bfcache. Ad esempio:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

Nei browser che supportano l'API Page Lifecycle, l'evento resume viene attivato quando le pagine vengono ripristinate dalla cache bf (immediatamente prima dell'evento pageshow) e quando un utente torna a visitare una scheda in background congelata. Se vuoi aggiornare lo stato di una pagina dopo che è stata bloccata (incluse le pagine nella bfcache), puoi utilizzare l'evento resume, ma se vuoi misurare il tasso di hit della bfcache del tuo sito, devi utilizzare l'evento pageshow. In alcuni casi, potresti dover utilizzare entrambi.

Per informazioni dettagliate sulle best practice per la misurazione della cache bfcache, consulta In che modo la cache bfcache influisce sulla misurazione di analisi e rendimento.

Osserva l'inserimento di bfcache in una pagina

L'evento pagehide viene attivato quando una pagina viene scaricata o quando il browser tenta di inserirla nella bfcache.

L'evento pagehide ha anche una proprietà persisted. Se è false, puoi essere certo che una pagina non sta per inserire la cache bfcache. Tuttavia, il fatto che persisted sia true non garantisce che una pagina venga memorizzata nella cache. Significa che il browser intende memorizzare la pagina nella cache, ma potrebbero esserci altri fattori che rendono impossibile la memorizzazione nella cache.

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

Analogamente, l'evento freeze viene attivato immediatamente dopo l'evento pagehide se persisted è true, ma ciò significa solo che il browser intende memorizzare nella cache la pagina. Potrebbe essere necessario eliminarlo per una serie di motivi spiegati in seguito.

Ottimizzare le pagine per la cache bfcache

Non tutte le pagine vengono memorizzate in bfcache e, anche quando una pagina viene memorizzata lì, non rimane per sempre. È fondamentale che gli sviluppatori comprendano cosa rende le pagine idonee (e non idonee) per la bfcache per massimizzare i tassi di hit della cache.

Le seguenti sezioni descrivono le best practice per aumentare le probabilità che il browser possa memorizzare le pagine nella cache.

Non utilizzare mai l'evento unload

Il modo più importante per ottimizzare per bfcache in tutti i browser è non utilizzare mai l'evento unload. Mai!

L'evento unload è problematico per i browser perché precede bfcache e molte pagine su internet operano con l'assunto (ragionevole) che una pagina non continuerà a esistere dopo l'attivazione dell'evento unload. Ciò rappresenta una sfida perché molte di queste pagine sono state anche create partendo dal presupposto che l'evento unload si attivasse ogni volta che un utente esce dal sito, il che non è più vero (e non è più vero da molto tempo).

Pertanto, i browser si trovano di fronte a un dilemma: devono scegliere tra qualcosa in grado di migliorare l'esperienza utente e, allo stesso tempo, rischiare di danneggiare la pagina.

Su computer, Chrome e Firefox hanno scelto di rendere le pagine non idonee per la memorizzazione nella cache bfcache se aggiungono un listener unload, il che è meno rischioso, ma squalifica molte pagine. Safari tenterà di memorizzare nella cache alcune pagine con un listener di eventi unload, ma per ridurre i potenziali danni non eseguirà l'evento unload quando un utente sta uscendo, il che rende l'evento molto inaffidabile.

Sui dispositivi mobili, Chrome e Safari tenteranno di memorizzare nella cache le pagine con un gestore di eventi unload, poiché il rischio di interruzione è inferiore, dato che l'evento unload è sempre stato estremamente inaffidabile sui dispositivi mobili. Firefox considera le pagine che utilizzano unload non idonee per la cache bfcache, tranne su iOS, che richiede a tutti i browser di utilizzare il motore di rendering WebKit e si comporta quindi come Safari.

Utilizza l'evento pagehide anziché l'evento unload. L'evento pagehide viene attivato in tutti i casi in cui viene attivato l'evento unload e anche quando una pagina viene inserita nella cache bfcache.

Infatti, Lighthouse dispone di un controllo no-unload-listeners che avvisa gli sviluppatori se il codice JavaScript nelle loro pagine (incluse le librerie di terze parti) aggiunge un ascoltatore di eventi unload.

A causa della sua inaffidabilità e dell'impatto sulle prestazioni di bfcache, Chrome sta cercando di ritirare l'evento unload.

Utilizzare il criterio di autorizzazione per impedire l'utilizzo di gestori di unload in una pagina

I siti che non utilizzano gestori di eventi unload possono assicurarsi che non vengano aggiunti utilizzando un Regolamento per le autorizzazioni.

Permission-Policy: unload=()

In questo modo, inoltre, le terze parti o le estensioni non rallentano il sito aggiungendo gestori di caricamento e rendendolo non idoneo per la bfcache.

Aggiungi solo beforeunload ascoltatori in modo condizionale

L'evento beforeunload non renderà le tue pagine non idonee per l'utilizzo di bfcache nei browser moderni bfcache, ma in precedenza lo era ed è ancora inaffidabile, quindi evita di utilizzarlo a meno che non sia assolutamente necessario.

Tuttavia, a differenza dell'evento unload, esistono utilizzi legittimi di beforeunload. Ad esempio, per avvisare l'utente del fatto che ha apportato modifiche non salvate, le perderà se esce dalla pagina. In questo caso, ti consigliamo di aggiungere gli ascoltatori beforeunload solo quando un utente ha modifiche non salvate e di rimuoverli immediatamente dopo il salvataggio delle modifiche non salvate.

Cosa non fare
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
Questo codice aggiunge un ascoltatore beforeunload in modo incondizionato.
Cosa fare
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
Questo codice aggiunge l'ascoltatore beforeunload solo quando è necessario (e lo rimuove quando non è necessario).

Riduci al minimo l'utilizzo di Cache-Control: no-store

Cache-Control: no-store è un'intestazione HTTP che i server web possono impostare sulle risposte per indicare al browser di non memorizzare la risposta in alcuna cache HTTP. Viene utilizzato per le risorse contenenti informazioni sensibili degli utenti, ad esempio le pagine protette da login.

Sebbene bfcache non sia una cache HTTP, storicamente, quando Cache-Control: no-store viene impostato sulla risorsa della pagina stessa (e non su una qualsiasi sottorisorsa), i browser hanno scelto di non archiviare la pagina in bfcache, pertanto tutte le pagine che utilizzano Cache-Control: no-store potrebbero non essere idonee per bfcache. Sono in corso dei lavori per modificare questo comportamento per Chrome nel rispetto della privacy.

Poiché Cache-Control: no-store limita l'idoneità di una pagina per la cache bfcache, deve essere impostato solo sulle pagine che contengono informazioni sensibili in cui la memorizzazione nella cache di qualsiasi tipo non è mai appropriata.

Utilizza Cache-Control: no-cache o Cache-Control: max-age=0 per le pagine che devono pubblicare sempre contenuti aggiornati e che non includono informazioni sensibili. Queste direttive chiedono al browser di convalidare nuovamente i contenuti prima di pubblicarli e non influiscono sull'idoneità di una pagina alla bfcache.

Tieni presente che quando una pagina viene ripristinata da bfcache, viene ripristinata dalla memoria, non dalla cache HTTP. Di conseguenza, le direttive come Cache-Control: no-cache o Cache-Control: max-age=0 non vengono prese in considerazione e non viene eseguita alcuna convalida prima che i contenuti vengano mostrati all'utente.

Tuttavia, si tratta comunque di un'esperienza utente migliore, in quanto i ripristini della bfcache sono istantanei e, poiché le pagine non rimangono nella bfcache per molto tempo, è improbabile che i contenuti siano obsoleti. Tuttavia, se i tuoi contenuti cambiano minuto per minuto, puoi recuperare eventuali aggiornamenti utilizzando l'evento pageshow, come descritto nella sezione successiva.

Aggiornare i dati inattivi o sensibili dopo il ripristino di bfcache

Se il tuo sito mantiene lo stato dell'utente, in particolare le informazioni sensibili dell'utente, questi dati devono essere aggiornati o cancellati dopo il ripristino di una pagina dalla cache bfcache.

Ad esempio, se un utente visita una pagina di pagamento e poi aggiorna il carrello della spesa, una navigazione a ritroso potrebbe potenzialmente mostrare informazioni obsolete se viene ripristinata una pagina non aggiornata dalla bfcache.

Un altro esempio più critico è quando un utente esce da un sito su un computer pubblico e l'utente successivo fa clic sul pulsante Indietro. Ciò potrebbe esporre dati privati che l'utente supponeva fossero stati cancellati al momento della disconnessione.

Per evitare situazioni come questa, è buona norma aggiornare sempre la pagina dopo un evento pageshow se event.persisted è true:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

Anche se idealmente dovresti aggiornare i contenuti, per alcune modifiche potresti voler forzare un ricaricamento completo. Il seguente codice controlla la presenza di un cookie specifico del sito nell'evento pageshow e ricarica la pagina se il cookie non viene trovato:

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

La ricarica ha il vantaggio di conservare la cronologia (per consentire la navigazione in avanti), ma in alcuni casi un reindirizzamento potrebbe essere più appropriato.

Ripristino di annunci e bfcache

Potrebbe essere allettante provare a evitare l'utilizzo di bfcache per pubblicare un nuovo insieme di annunci a ogni navigazione avanti/indietro. Tuttavia, oltre ad avere un impatto sul rendimento, è discutibile se questo comportamento porti a un migliore coinvolgimento con gli annunci. Gli utenti potrebbero aver notato un annuncio su cui intendevano fare clic, ma non essere in grado di farlo perché hanno ricaricato la pagina anziché ripristinare l'annuncio dalla cache bf. È importante testare questo scenario, idealmente con un test A/B, prima di fare supposizioni.

Per i siti che vogliono aggiornare gli annunci al ripristino della bfcache, l'aggiornamento solo degli annunci nell'evento pageshow quando event.persisted è true consente di farlo senza influire sul rendimento della pagina. Rivolgiti al tuo fornitore di annunci, ma ecco un esempio di come eseguire questa operazione con il Tag publisher di Google.

Evita riferimenti a window.opener

Nei browser meno recenti, se una pagina veniva aperta utilizzando window.open() da un link con target=_blank, senza specificare rel="noopener", la pagina di apertura conteneva un riferimento all'oggetto window della pagina aperta.

Oltre a essere un rischio per la sicurezza, una pagina con un riferimento a window.opener non nullo non può essere inserita in modo sicuro nella cache bfcache, perché questo potrebbe interrompere le pagine che tentano di accedervi.

Di conseguenza, è meglio evitare di creare riferimenti a window.opener. Puoi farlo utilizzando rel="noopener", se possibile (tieni presente che ora è l'impostazione predefinita in tutti i browser moderni). Se il tuo sito richiede l'apertura di una finestra e il relativo controllo tramite window.postMessage() o il riferimento diretto all'oggetto window, né la finestra aperta né l'elemento che la apre saranno idonei per la bfcache.

Chiudi le connessioni aperte prima che l'utente esca dalla pagina

Come accennato in precedenza, quando una pagina viene conservata nella bfcache, vengono messe in pausa tutte le attività JavaScript pianificate e riprese quando la pagina viene rimossa dalla cache.

Se queste attività JavaScript pianificate accedono solo alle API DOM o ad altre API isolate solo alla pagina corrente, la sospensione di queste attività mentre la pagina non è visibile all'utente non causerà alcun problema.

Tuttavia, se queste attività sono collegate ad API accessibili anche da altre pagine della stessa origine (ad esempio IndexedDB, Web Locks, WebSockets), ciò può essere problematico perché la messa in pausa di queste attività potrebbe impedire l'esecuzione del codice in altre schede.

Di conseguenza, alcuni browser non tenteranno di inserire una pagina nella cache bf nei seguenti scenari:

Se la tua pagina utilizza una di queste API, ti consigliamo vivamente di chiudere le connessioni e di rimuovere o scollegare gli osservatori durante l'evento pagehide o freeze. In questo modo, il browser può memorizzare nella cache la pagina in sicurezza senza il rischio di influire su altre schede aperte.

Se la pagina viene ripristinata dalla bfcache, puoi riaprirla o ricollegarti a queste API durante l'evento pageshow o resume.

L'esempio seguente mostra come assicurarsi che le pagine che utilizzano IndexedDB siano idonee per la bfcache chiudendo una connessione aperta nell'ascoltatore di eventi pagehide:

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

Verificare che le pagine siano memorizzabili nella cache

Chrome DevTools può aiutarti a testare le tue pagine per assicurarti che siano ottimizzate per la cache bf e identificare eventuali problemi che potrebbero impedirne l'idoneità.

Per testare una pagina:

  1. Vai alla pagina in Chrome.
  2. In DevTools, vai ad Applicazione -> Cache avanti e indietro.
  3. Fai clic sul pulsante Esegui test. DevTools tenta quindi di passare da una pagina all'altra e viceversa per determinare se la pagina può essere ripristinata dalla cache bf.
Riquadro della cache back-forward in DevTools
Il riquadro Cache back-forward in DevTools.

Se il test ha esito positivo, nel riquadro viene visualizzato il messaggio "Ripristinato dalla cache back-forward".

DevTools segnala che una pagina è stata ripristinata correttamente dalla cache bf
Una pagina ripristinata correttamente.

Se l'operazione non va a buon fine, il riquadro ne indica il motivo. Se il motivo è un problema che puoi risolvere come sviluppatore, il riquadro lo contrassegna come Azione possibile.

DevTools segnala l'impossibilità di ripristinare una pagina dalla cache bfcache
Un test bfcache non riuscito con un risultato utile.

In questo esempio, l'utilizzo di un listener di eventi unload rende la pagina non idonea per la cache bfcache. Per risolvere il problema, passa da unload a pagehide:

Cosa fare
window.addEventListener('pagehide', ...);
Cosa non fare
window.addEventListener('unload', ...);

Lighthouse 10.0 ha anche aggiunto un controllo bfcache, che esegue un test simile. Per ulteriori informazioni, consulta la documentazione del controllo bfcache.

In che modo bfcache influisce su analisi e misurazione del rendimento

Se utilizzi uno strumento di analisi per misurare le visite al tuo sito, potresti notare una diminuzione del numero totale di visualizzazioni di pagina registrate man mano che Chrome attiva bfcache per un numero maggiore di utenti.

In effetti, è probabile che tu stia già sottostimando le visualizzazioni di pagina di altri browser che implementano bfcache, perché molte librerie di analisi di uso comune non misurano i ripristini di bfcache come nuove visualizzazioni di pagina.

Per includere i ripristini bfcache nel numero di visualizzazioni di pagina, imposta i listener per l'evento pageshow e controlla la proprietà persisted.

L'esempio seguente mostra come eseguire questa operazione con Google Analytics. È probabile che altri strumenti di analisi utilizzino una logica simile:

// Send a pageview when the page is first loaded.
gtag('event', 'page_view');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

Misurare la percentuale di hit della cache bf

Potresti anche valutare se è stata utilizzata la cache bfcache per identificare le pagine che non la utilizzano. Per farlo, puoi misurare il tipo di navigazione per i caricamenti pagina:

// Send a navigation_type when the page is first loaded.
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

Calcola il rapporto di hit della cache bf utilizzando i conteggi per le navigazioni back_forward e back_forward_cache.

È importante capire che esistono vari scenari, al di fuori del controllo dei proprietari del sito, in cui la navigazione Indietro/Avanti non utilizza bfcache, tra cui:

  • Quando l'utente chiude il browser e lo riapre
  • Quando l'utente duplica una scheda
  • Quando l'utente chiude e riapre una scheda.

In alcuni di questi casi, il tipo di navigazione originale potrebbe essere preservato da alcuni browser e quindi potrebbe essere visualizzato un tipo di back_forward nonostante non si tratti di navigazione Indietro/Avanti.

Anche senza queste esclusioni, la cache bf verrà eliminata dopo un periodo di tempo per risparmiare memoria.

Di conseguenza, i proprietari di siti web non dovrebbero aspettarsi un rapporto hit di bfcache del 100% per tutte le navigazioni in back_forward. Tuttavia, la misurazione del loro rapporto può essere utile per identificare le pagine in cui la pagina stessa impedisce l'utilizzo della cache back-forward per un'alta percentuale di navigazioni avanti e indietro.

Il team di Chrome ha aggiunto l'API NotRestoredReasons per aiutare a identificare i motivi per cui le pagine non utilizzano la cache bf, in modo che gli sviluppatori possano migliorare le relative percentuali di hit. Il team di Chrome ha anche aggiunto tipi di navigazione a CrUX, rendendo possibile vedere il numero di navigazioni bfcache anche senza misurarlo autonomamente.

Misurazione del rendimento

bfcache può anche influire negativamente sulle metriche sul rendimento raccolte sul campo, in particolare quelle che misurano i tempi di caricamento delle pagine.

Poiché le navigazioni bfcache ripristinano una pagina esistente anziché avviare un nuovo caricamento di pagina, il numero totale di caricamenti di pagina raccolti diminuirà quando bfcache è attivato. Ciò che è fondamentale, però, è che i caricamenti di pagine sostituiti dai ripristini di bfcache probabilmente erano tra i più rapidi nel tuo set di dati. Questo perché le navigazioni avanti e indietro, per definizione, sono visite ripetute e i caricamenti di pagine ripetuti sono in genere più rapidi rispetto ai caricamenti di pagine dei visitatori di prima volta (a causa della memorizzazione nella cache HTTP, come accennato in precedenza).

Il risultato è un minor numero di caricamenti pagina veloci nel set di dati, il che probabilmente disallinea la distribuzione più lentamente, nonostante il fatto che le prestazioni sperimentate dall'utente siano probabilmente migliorate.

Esistono alcuni modi per risolvere il problema. Una consiste nell'annotare tutte le metriche relative al caricamento della pagina con il rispettivo tipo di navigazione: navigate, reload, back_forward o prerender. In questo modo puoi continuare a monitorare il tuo rendimento all'interno di questi tipi di navigazione, anche se la distribuzione complessiva è negativa. Consigliamo questo approccio per le metriche di caricamento della pagina non incentrate sull'utente, come il tempo di risposta (TTFB).

Per le metriche incentrate sull'utente come i Core Web Vitals, un'opzione migliore è segnalare un valore che rappresenti in modo più accurato l'esperienza dell'utente.

Impatto sui Core Web Vitals

Core Web Vitals misurano l'esperienza dell'utente su una pagina web in una serie di dimensioni (velocità di caricamento, interattività, stabilità visiva) e, poiché gli utenti sperimentano i ripristini della bfcache come navigazioni più veloci rispetto ai caricamenti completi della pagina, è importante che le metriche di Core Web Vitals lo riflettano. Dopotutto, a un utente non importa se bfcache sia stato abilitato o meno, gli interessa solo che la navigazione sia stata veloce.

Gli strumenti che raccolgono e generano report sulle metriche Core Web Vitals, come il Chrome User Experience Report, considerano i ripristini di bfcache come visite di pagine separate nel loro set di dati. Sebbene non esistano API dedicate per il rendimento web per misurare queste metriche dopo i ripristini di bfcache, puoi approssimare i relativi valori utilizzando le API web esistenti:

  • Per Largest Contentful Paint (LCP), utilizza il delta tra il timestamp dell'evento pageshow e il timestamp del frame disegnato successivo, perché tutti gli elementi del frame verranno disegnati contemporaneamente. Nel caso di un ripristino della bfcache, LCP e FCP sono uguali.
  • Per Interaction to Next Paint (INP), continua a utilizzare lo strumento di monitoraggio del rendimento esistente, ma reimposta il valore INP corrente su 0.
  • Per Cumulative Layout Shift (CLS), continua a utilizzare Performance Observer, ma reimposta il valore CLS attuale su 0.

Per ulteriori dettagli su come bfcache influisce su ogni metrica, consulta le singole pagine delle guide alle metriche di Core Web Vitals. Per un esempio specifico di come implementare le versioni bfcache di queste metriche, consulta la RP che le aggiunge alla libreria JS web-vitals.

La libreria JavaScript web-vitals supporta i ripristini bfcache nelle metriche registrate.

Risorse aggiuntive