In breve, la risposta rapida
8 min di letturaLa bfcache (back/forward cache) conserva in memoria un'istantanea completa della pagina quando il visitatore se ne va, così un clic su indietro o avanti la ripristina subito, senza ricaricarla. Chrome, Firefox e Safari ne hanno una. Poiché la pagina non viene caricata di nuovo, uno script di analytics che conta le pageview solo al caricamento perde il ripristino. Ascolta l'evento pageshow e controlla event.persisted per contare i ripristini, ed evita i listener unload, Cache-Control: no-store e le connessioni aperte che rendono una pagina non idonea.
Che cos'è la bfcache?
La bfcache, abbreviazione di back/forward cache, è un'ottimizzazione del browser che conserva in memoria un'istantanea completa della pagina quando il visitatore se ne va. Così un clic su indietro o avanti ripristina quella pagina all'istante, invece di ricaricarla da zero. web.dev la definisce come «un'ottimizzazione del browser che permette una navigazione avanti e indietro istantanea» e ne descrive il meccanismo: «invece di distruggere una pagina quando l'utente si sposta altrove, rimandiamo la distruzione e mettiamo in pausa l'esecuzione del JS. Se l'utente torna indietro a breve, rendiamo di nuovo visibile la pagina e riprendiamo l'esecuzione del JS.»
Tutti i principali browser ce l'hanno: Chrome dalla versione 96, Firefox e Safari. I clic su indietro e avanti pesano parecchio sulla navigazione. web.dev riporta che «i dati di utilizzo di Chrome mostrano che 1 navigazione su 10 su desktop e 1 su 5 su mobile è un'azione di indietro o avanti.»
Per le analytics conta soprattutto ciò che non succede durante un ripristino. Non viene richiesto nessun HTML, nessuno script riparte dall'inizio e non scatta alcun evento load. Il tuo tracker si risveglia esattamente dove era stato messo in pausa.

In che cosa la bfcache è diversa dalla cache HTTP?
La bfcache conserva l'intera pagina attiva, mentre la cache HTTP conserva le singole risposte. web.dev lo spiega così: «la bfcache è un'istantanea dell'intera pagina in memoria, compreso l'heap JavaScript, mentre la cache HTTP contiene solo le risposte alle richieste fatte in precedenza.» Una pagina servita dalla cache HTTP viene comunque caricata: il browser analizza l'HTML, esegue ogni script e fa scattare load, quindi il tuo tracker invia una normale pageview. Una pagina ripristinata dalla bfcache salta tutto questo.
Anche timer e promise vanno in pausa. web.dev osserva che «i browser mettono in pausa i timer in sospeso e le promise non risolte per le pagine nella bfcache» e li riprendono al ripristino. Un heartbeat o un timer di engagement riparte dopo l'intervallo, senza contarlo.
Quali pagine sono idonee alla bfcache?
Una pagina è idonea alla bfcache a meno che qualcosa al suo interno renda la memorizzazione poco sicura, e i blocchi più comuni dipendono da te. La tabella elenca quelli che web.dev e la documentazione di Chrome segnalano.
| Blocco | Effetto sulla bfcache | Soluzione |
|---|---|---|
Listener unload | Non idonea in Chrome e Firefox su desktop; Firefox anche su mobile, tranne iOS | Usa pagehide al suo posto |
Cache-Control: no-store sulla pagina | In passato escludeva la pagina dalla bfcache | Usa no-cache o max-age=0, a meno che la pagina sia sensibile |
Listener beforeunload incondizionato | Nei browser moderni non blocca più, ma in passato sì, secondo web.dev | Aggiungilo solo quando ci sono modifiche non salvate |
Riferimento window.opener | Una pagina con un opener non nullo «non può essere messa in sicurezza nella bfcache» | Usa rel="noopener" |
| Connessione IndexedDB aperta | Alcuni browser non memorizzano la pagina | Chiudila su pagehide, riaprila su pageshow |
fetch() o XMLHttpRequest in corso | Alcuni browser non memorizzano la pagina | Lascia finire le richieste o interrompile su pagehide |
| Connessione WebSocket o WebRTC aperta | Blocca in alcuni browser; Chrome 149 e successivi e Safari non bloccano con WebSocket aperti | Chiudila su pagehide |
Alcuni mancati ripristini non c'entrano nulla con il tuo codice. web.dev elenca le navigazioni avanti o indietro che non usano la bfcache «quando l'utente chiude il browser e lo riavvia», «quando l'utente duplica una scheda» e «quando l'utente chiude una scheda e la riapre», e precisa che i browser scartano le pagine in cache dopo un certo tempo per risparmiare memoria. Un tasso di successo del 100% non è un obiettivo realistico.
Gli iframe seguono la pagina principale. Un iframe non viene memorizzato separatamente, e un iframe che usa un'API bloccante può tenere l'intera pagina fuori dalla bfcache.
Come segnalano la bfcache pageshow e pagehide?
Gli eventi pageshow e pagehide segnalano la bfcache tramite la proprietà persisted. Su pageshow, persisted vale true quando la pagina è tornata dalla bfcache e false in un caricamento normale. Su pagehide, persisted a true significa che il browser intende memorizzare la pagina, anche se web.dev sottolinea che «non garantisce che la pagina verrà messa in cache».
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
console.log('This page was restored from the bfcache.');
} else {
console.log('This page was loaded normally.');
}
});pageshow «scatta subito dopo l'evento load quando la pagina si carica per la prima volta e ogni volta che la pagina viene ripristinata dalla bfcache.» Per le analytics questo dettaglio conta, come vedrai nella prossima sezione. I browser Chromium fanno scattare anche gli eventi del Page Lifecycle freeze e resume quando una pagina entra ed esce dalla bfcache, ma web.dev fa notare che per misurare il tasso di successo della tua bfcache serve pageshow.

Perché le analytics perdono o contano due volte le navigazioni all'indietro?
Le analytics perdono le navigazioni all'indietro perché un ripristino dalla bfcache non riesegue gli script della pagina, quindi un tracker che invia la pageview al caricamento resta in silenzio. web.dev avverte i proprietari dei siti che potrebbero notare «un calo del numero totale di pageview riportate, man mano che Chrome abilita la bfcache per più utenti», e aggiunge che molti siti stanno «già sottostimando le pageview provenienti da altri browser che implementano la bfcache, perché molte librerie di analytics diffuse non misurano i ripristini dalla bfcache come nuove pageview.»
Il doppio conteggio nasce dalla correzione opposta, fatta con poca attenzione. Poiché pageshow scatta anche a ogni caricamento normale, un listener che invia una pageview a ogni pageshow senza controllare persisted ne manda due per caricamento: una dall'avvio normale del tracker, una dal listener.
Lo stesso meccanismo produce altre distorsioni:
Dashboard in tempo reale
Monitoraggio degli obiettivi
Tracciamento senza cookie
- Vuoti nell'engagement. I timer in pausa riprendono al ripristino, quindi timer di engagement e heartbeat saltano il tempo in cui la pagina è rimasta in memoria.
- Eventi di uscita che non partono mai. Una pagina che entra nella bfcache non fa mai scattare
unload. La guida beforeunload vs pagehide spiega perché i beacon di uscita vanno agganciati apagehideevisibilitychange. - Pagine più veloci che sembrano più lente. web.dev spiega che i ripristini prendono il posto delle visite ripetute, che sono tra i caricamenti più rapidi di un dataset, quindi i dati sui tempi di caricamento peggiorano anche se i visitatori hanno avuto un'esperienza più veloce.
- Conteggi misti. Una navigazione all'indietro che non trova la bfcache ricarica tutta la pagina e viene contata, mentre una che la trova no. Lo stesso schema di clic produce numeri diversi a seconda dell'idoneità.
La guida pageview, sessioni e utenti mostra come queste lacune si ripercuotono sulle metriche per sessione.
- Il tracker invia la pageview al caricamento
- Un ripristino dalla bfcache non fa scattare nessun evento load
- Il clic su indietro non viene mai contato
- pageshow scatta anche a ogni caricamento normale
- Ogni caricamento invia due pageview
- I ripristini vengono contati, ma i caricamenti sono raddoppiati
- Il listener invia solo quando event.persisted è true
- Un caricamento normale resta a una pageview
- Ogni ripristino ne aggiunge esattamente una
Come si contano correttamente i ripristini dalla bfcache?
I ripristini dalla bfcache si contano aggiungendo un listener pageshow che invia una visualizzazione di pagina solo quando event.persisted è true, poi verificando che ogni clic su indietro produca esattamente un solo hit.
- Aggiungi il listener. L'esempio di Google Analytics di web.dev invia
gtag('event', 'page_view')dentroif (event.persisted), lasciando il caricamento normale alla visualizzazione di pagina predefinita. - Etichetta il tipo di navigazione. Per misurare il tuo hit ratio, web.dev disattiva la visualizzazione di pagina predefinita con
send_page_view: false, ne invia una connavigation_typepreso daperformance.getEntriesByType('navigation')[0].typee usanavigation_type: 'back_forward_cache'per i ripristini. Confronta poi i conteggi diback_forwardeback_forward_cache. - Esegui il test di DevTools. In Chrome DevTools apri Application, poi Back-forward Cache, e clicca su Run Test. Se il test passa, leggi "Restored from back-forward cache". Se fallisce, vedi l'elenco dei motivi, con quelli risolvibili segnati come Actionable.
- Raccogli i motivi dalle visite reali. La proprietà
notRestoredReasonsdella voce di navigation timing indica perché una pagina non è stata ripristinata. La documentazione di Chrome dice che "has shipped from Chrome 123", con motivi comeunload-listenereresponse-cache-control-no-store. - Risolvi i blocchi. Sostituisci
unloadconpagehide, toglino-storedalle pagine che non contengono dati sensibili e chiudi le connessioni IndexedDB o WebSocket supagehide.
Anche le metriche di performance richiedono la stessa attenzione. web.dev spiega che strumenti come il Chrome User Experience Report trattano i ripristini come visite separate, e che la libreria web-vitals li supporta. Dopo un ripristino, il Largest Contentful Paint si misura dal timestamp di pageshow fino al frame successivo disegnato, mentre Cumulative Layout Shift e INP ripartono da 0.
Come influisce la bfcache sui dati di Flowsery?
La documentazione di Flowsery non descrive come il suo tracker tratti un ripristino dalla bfcache, quindi prova sul tuo sito prima di aggiungere qualsiasi codice. La vista analisi in tempo reale di Flowsery mostra ogni visualizzazione di pagina sulla tua dashboard nel momento in cui avviene, e rende il controllo rapido: apri una pagina, clicca su un link, premi indietro e guarda se la pagina ripristinata compare come nuova visualizzazione. Esegui prima il test bfcache di DevTools, così sai che la pagina è stata ripristinata e non ricaricata. Se i ripristini non compaiono e vuoi contarli, l'SDK npm di Flowsery espone un metodo trackPageview() che puoi chiamare da un listener pageshow che controlla event.persisted, evitando il doppio conteggio che causerebbe un listener privo di quel controllo.
Domande frequenti
Tutti i browser hanno una bfcache?
Sì, tutti i principali browser ne hanno una. web.dev elenca Chrome dalla versione 96, Firefox e Safari. Ogni browser ha regole di idoneità proprie, ed è per questo che la stessa pagina può finire nella cache in un browser e venire ricaricata in un altro.
Un ripristino dalla bfcache attiva l'evento load?
No. Un ripristino rende di nuovo visibile la pagina in pausa e riprende il suo JavaScript, quindi load e DOMContentLoaded non vengono attivati. Viene invece attivato l'evento pageshow, con persisted impostato su true.
Perché le mie visualizzazioni di pagina sono calate dopo che Chrome ha esteso la bfcache?
Più clic su indietro e avanti sono diventati ripristini invece di ricaricamenti, e molti script di analytics contano le visualizzazioni di pagina solo al caricamento. web.dev descrive proprio questo calo. Se vuoi contare i ripristini, aggiungi un listener pageshow che invii una visualizzazione di pagina quando event.persisted è true.
Cache-Control: no-store disattiva la bfcache?
Sulla pagina stessa, storicamente ha escluso le pagine dalla bfcache. web.dev consiglia di usarlo solo per le pagine con informazioni sensibili, e di usare no-cache o max-age=0 per quelle che hanno solo bisogno di contenuti aggiornati. Nessuno dei due influisce sull'idoneità.
Come verifico se una pagina è idonea alla bfcache?
In Chrome DevTools vai su Application, poi Back-forward Cache, e clicca su Run Test. Il pannello indica se la pagina è stata ripristinata e, in caso contrario, elenca i motivi del blocco. Per le visite reali, leggi notRestoredReasons dalla voce di navigation timing.
La bfcache funziona dentro una single-page app?
No. web.dev afferma che la bfcache "doesn't work for 'soft navigations' within a single-page app." Si applica quando un visitatore esce dall'app e ci torna con il pulsante indietro: se la pagina è idonea, può essere ripristinata l'intera app invece di ripartire da zero.
Cosa succede a timer e heartbeat mentre una pagina è nella bfcache?
I browser mettono in pausa i timer in sospeso e le promise non risolte, poi li riprendono al ripristino. Un heartbeat o un timer di coinvolgimento riparte dopo la pausa, quindi il tempo che la pagina ha passato in memoria non viene contato come coinvolgimento.
Un listener unload tiene una pagina fuori dalla bfcache?
Sì, in Chrome e Firefox su desktop, e in Firefox su mobile tranne iOS. Sostituisci unload con pagehide e la pagina resta idonea.
Come evito di contare due volte le visualizzazioni di pagina con un listener pageshow?
pageshow si attiva a ogni caricamento normale oltre che a ogni ripristino, quindi invia la visualizzazione di pagina solo quando event.persisted è true. L'avvio normale del tracker copre già il caricamento regolare. Poi premi indietro su una pagina di prova e controlla che ogni clic produca esattamente un hit.
Flowsery conta automaticamente i ripristini dalla bfcache?
La documentazione di Flowsery non lo descrive, quindi prova sul tuo sito. Apri una pagina, clicca su un link, premi indietro e guarda nella vista di analisi in tempo reale se compare una nuova visualizzazione di pagina. Se non compare, chiama trackPageview() dall'SDK npm dentro un listener pageshow che controlla event.persisted.
Questo articolo ti è stato utile?
Facci sapere cosa ne pensi!
Vedici più spesso su Google
Con un clic imposti Flowsery come fonte preferita e i nostri articoli salgono in Notizie principali, Modalità AI e AI Overview.
Prima di andare...
Flowsery
Analytics per il tuo sito che parte dalle entrate
Monitora ogni visitatore, sorgente e conversione in tempo reale. Semplice, potente e senza cookie.
Dashboard in tempo reale
Monitoraggio degli obiettivi
Tracciamento senza cookie
Termini del glossario correlati
Come il tracking delle SPA conta le visualizzazioni di pagina quando la pagina non si ricarica mai
Un tracking SPA accurato significa una pageview per schermata con il referrer giusto. Come lavorano insieme History API, pageview virtuali ed eventi di cronologia di GA4.


Perché il bounce rate di GA4 è solo l'engagement rate al contrario
Il bounce rate di GA4 è la quota di sessioni senza interazione. Come lo definisce Google, in cosa differisce da Universal Analytics e dove aggiungerlo.


Cosa conta il report Pagine di destinazione di GA4 e dove resta vuoto
Il report Pagine di destinazione di GA4 elenca la prima pagina di ogni sessione. Dove trovarlo, le metriche predefinite, perché compaiono righe (not set) e come aggiungere la fonte.


Come il tracciamento della ricerca interna di GA4 registra ciò che digitano i visitatori
Configura la ricerca interna di GA4 con la misurazione avanzata, aggiungi i tuoi parametri di query, trova la dimensione Termine di ricerca e traccia le ricerche senza URL.


Impostare le proprietà utente di GA4 e analizzarle nei report
Imposta le proprietà utente di GA4 con gtag o Tag Manager, registrale come dimensioni personalizzate a livello utente e resta entro il limite di 25 proprietà.


Come collegare Search Console a GA4 e pubblicarne i report
Scopri come collegare Search Console a GA4 da Amministrazione, quali ruoli ti servono, come pubblicare i due report nella Raccolta e quali dati non si possono unire.
Articoli correlati


Che fine ha fatto la deprecazione dei cookie di terze parti di Chrome
La deprecazione dei cookie di terze parti in Chrome va da un piano del 2020 a un'inversione di rotta nel 2025. Ogni annuncio di Google, cosa fa Chrome oggi e cosa significa.


Perché il CNAME cloaking non nasconde più i tracker a Safari o Brave
I tracker usavano il CNAME cloaking per spacciarsi per un tuo sottodominio. Come funziona il trucco DNS, perché Safari limita i suoi cookie a 7 giorni e come Brave e uBlock lo smascherano.


Come il cookie syncing abbina gli ID pubblicitari tra siti
Le aziende ad-tech usano il cookie syncing per scambiarsi gli ID utente con redirect e pixel. Cosa fanno Safari, Firefox e Chrome e perché l'analytics non ne ha bisogno.

