TL;DR, Respuesta rápida
9 min de lecturaLa bfcache (caché de avance y retroceso) guarda en memoria una instantánea completa de una página cuando el visitante sale de ella, así que un clic en atrás o adelante la restaura al instante sin recargarla. Chrome, Firefox y Safari tienen una. Como la página no vuelve a cargarse, un script de analítica que solo cuenta páginas vistas al cargar no registra la restauración. Escucha pageshow y comprueba event.persisted para contar las restauraciones, y evita los listeners de unload, Cache-Control: no-store y las conexiones abiertas que hacen que una página no sea apta.
¿Qué es la bfcache?
La bfcache, abreviatura de back/forward cache o caché de avance y retroceso, es una optimización del navegador que guarda en memoria una instantánea completa de una página cuando el visitante sale de ella, de modo que un clic en atrás o adelante restaura esa página al instante en lugar de cargarla de nuevo. web.dev la define como "a browser optimization that enables instant back and forward navigation," y describe el mecanismo: "instead of destroying a page when the user navigates away, we postpone destruction and pause JS execution. If the user navigates back soon, we make the page visible again and unpause JS execution."
Todos los navegadores principales tienen una: Chrome desde la versión 96, Firefox y Safari. Los clics en atrás y adelante son una parte grande de la navegación. web.dev informa de que "Chrome usage data shows that 1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward."
Para la analítica, lo importante es lo que no ocurre en una restauración. No se pide HTML, ningún script se ejecuta desde el principio y no se dispara ningún evento load. Tu tracker se despierta exactamente donde se quedó pausado.

¿En qué se diferencia la bfcache de la caché HTTP?
La bfcache guarda la página viva entera, mientras que la caché HTTP guarda respuestas individuales. web.dev lo explica así: "bfcache is a snapshot of the entire page in memory, including the JavaScript heap, whereas the HTTP cache contains only the responses for previously made requests." Una página servida desde la caché HTTP sigue cargándose: el navegador analiza el HTML, ejecuta todos los scripts y dispara load, así que tu tracker envía una página vista normal. Una página restaurada desde la bfcache se salta todo eso.
Los temporizadores y las promesas también se pausan. web.dev señala que "browsers pause any pending timers or unresolved promises for pages in bfcache" y los reanudan al restaurar, así que un heartbeat o un temporizador de interacción continúa después del hueco en lugar de contarlo.
¿Qué páginas son aptas para la bfcache?
Una página es apta para la bfcache salvo que algo en ella haga inseguro guardarla, y los bloqueos más comunes dependen de ti. La tabla recoge los que señalan web.dev y la documentación de Chrome.
| Bloqueo | Efecto en la bfcache | Solución |
|---|---|---|
Listener de unload | No apta en Chrome y Firefox de escritorio; en Firefox también en móvil salvo iOS | Usa pagehide en su lugar |
Cache-Control: no-store en la página | Históricamente deja la página fuera de la bfcache | Usa no-cache o max-age=0 salvo que la página sea sensible |
Listener de beforeunload incondicional | Ya no bloquea en los navegadores modernos, pero antes sí, según web.dev | Añádelo solo mientras haya cambios sin guardar |
Referencia a window.opener | Una página con un opener no nulo "can't safely be put into bfcache" | Usa rel="noopener" |
| Conexión IndexedDB abierta | Algunos navegadores no guardan la página | Ciérrala en pagehide y vuelve a abrirla en pageshow |
fetch() o XMLHttpRequest en curso | Algunos navegadores no guardan la página | Deja que las peticiones terminen o cancélalas en pagehide |
| Conexión WebSocket o WebRTC abierta | Bloquea en algunos navegadores; Chrome 149 y posteriores y Safari no bloquean con WebSockets abiertos | Ciérrala en pagehide |
Algunos fallos no tienen nada que ver con tu código. web.dev enumera navegaciones hacia atrás o adelante que no usan la bfcache "when the user quits the browser and starts it again," "when the user duplicates a tab," y "when the user closes a tab and reopens it," y señala que los navegadores descartan las páginas guardadas pasado un tiempo para ahorrar memoria. Una tasa de aciertos del 100% no es un objetivo realista.
Los iframes siguen a la página principal. Un iframe no se guarda por separado, y un iframe que usa una API bloqueante puede dejar la página entera fuera de la bfcache.
¿Cómo informan pageshow y pagehide sobre la bfcache?
Los eventos pageshow y pagehide informan sobre la bfcache mediante su propiedad persisted. En pageshow, persisted vale true cuando la página vuelve de la bfcache y false en una carga normal. En pagehide, que persisted valga true significa que el navegador tiene intención de guardar la página, aunque web.dev insiste en que eso "doesn't guarantee that a page will be cached."
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 "fires right after the load event when the page is initially loading and any time the page is restored from bfcache." Ese detalle importa para la analítica, como muestra la siguiente sección. Los navegadores basados en Chromium también disparan los eventos de Page Lifecycle freeze y resume cuando una página entra en la bfcache y sale de ella, pero web.dev señala que medir tu tasa de aciertos de la bfcache requiere pageshow.

¿Por qué la analítica pierde o cuenta dos veces las navegaciones hacia atrás?
La analítica pierde las navegaciones hacia atrás porque una restauración desde la bfcache no vuelve a ejecutar los scripts de la página, así que un tracker que envía su página vista al cargar no dice nada. web.dev avisa a los propietarios de sitios de que pueden notar "a decrease in the total number of pageviews reported as Chrome enables bfcache for more users," y añade que muchos sitios ya están "already underreporting pageviews from other browsers that implement bfcache, because many popular analytics libraries don't measure bfcache restores as new pageviews."
El doble conteo viene de aplicar sin cuidado el arreglo contrario. Como pageshow también se dispara en cada carga normal, un listener que envía una página vista en cada pageshow sin comprobar persisted envía dos páginas vistas por carga: una del arranque normal del tracker y otra del listener.
Del mismo mecanismo salen otras distorsiones:
Panel en tiempo real
Seguimiento de objetivos
Rastreo sin cookies
- Huecos en la interacción. Los temporizadores pausados se reanudan al restaurar, así que los temporizadores de interacción y los heartbeats se saltan el tiempo que la página pasó en memoria.
- Eventos de salida que nunca se envían. Una página que entra en la bfcache nunca dispara
unload. La guía de beforeunload frente a pagehide explica por qué los beacons de salida deben ir enpagehideyvisibilitychange. - Páginas más rápidas que parecen más lentas. web.dev explica que las restauraciones sustituyen a las visitas repetidas, que están entre las cargas de página más rápidas de un conjunto de datos, así que los datos de tiempo de carga se inclinan hacia lo lento aunque los visitantes hayan tenido una experiencia más rápida.
- Recuentos mezclados. Una navegación hacia atrás que no usa la bfcache hace una recarga completa y se cuenta, mientras que una que sí la usa no se cuenta. El mismo patrón de clics produce cifras distintas según la aptitud de la página.
La guía de páginas vistas frente a sesiones frente a usuarios muestra cómo estos huecos se trasladan a las métricas por sesión.
- El tracker envía la página vista al cargar
- Una restauración desde la bfcache no dispara load
- El clic hacia atrás nunca se cuenta
- pageshow también se dispara en cada carga normal
- Cada carga envía dos páginas vistas
- Las restauraciones se cuentan, pero las cargas se duplican
- El listener envía solo cuando event.persisted es true
- Una carga normal se queda en una página vista
- Cada restauración suma exactamente una
¿Cómo cuentas correctamente las restauraciones desde la bfcache?
Las restauraciones desde la bfcache se cuentan añadiendo un listener de pageshow que envía una página vista solo cuando event.persisted vale true, y comprobando después que cada clic en atrás produce exactamente un hit.
- Añade el listener. El ejemplo de Google Analytics de web.dev envía
gtag('event', 'page_view')dentro deif (event.persisted)y deja la carga normal a la página vista predeterminada. - Etiqueta el tipo de navegación. Para medir tu tasa de aciertos, web.dev desactiva la página vista predeterminada con
send_page_view: false, envía una connavigation_typea partir deperformance.getEntriesByType('navigation')[0].typey envíanavigation_type: 'back_forward_cache'en las restauraciones. Compara los recuentos deback_forwardcon los deback_forward_cache. - Ejecuta la prueba de DevTools. En Chrome DevTools, abre Application, después Back-forward Cache, y haz clic en Run Test. Si pasa, verás "Restored from back-forward cache"; si falla, se listan los motivos y se marcan como Actionable los que puedes corregir.
- Recoge los motivos de visitas reales. La propiedad
notRestoredReasonsde la entrada de navigation timing indica por qué no se restauró una página. La documentación de Chrome dice que "has shipped from Chrome 123," con motivos comounload-listeneryresponse-cache-control-no-store. - Corrige los bloqueos. Sustituye
unloadporpagehide, quitano-storede las páginas que no son sensibles y cierra las conexiones IndexedDB o WebSocket enpagehide.
Las métricas de rendimiento necesitan el mismo cuidado. web.dev explica que herramientas como el Chrome User Experience Report tratan las restauraciones como visitas de página separadas, y que la librería web-vitals admite las restauraciones. En una restauración, el Largest Contentful Paint se mide desde la marca de tiempo de pageshow hasta el siguiente fotograma pintado, mientras que el Cumulative Layout Shift y el INP vuelven a 0.
¿Cómo afecta la bfcache a los datos de Flowsery?
La documentación de Flowsery no describe cómo trata su tracker una restauración desde la bfcache, así que pruébalo en tu propio sitio antes de añadir código. La vista de analítica en tiempo real de Flowsery muestra cada página vista en tu panel en el momento en que ocurre, lo que hace la comprobación rápida: abre una página, haz clic en un enlace, pulsa atrás y mira si la página restaurada aparece como una página vista nueva. Ejecuta antes la prueba de bfcache de DevTools para saber que la página se restauró y no se recargó. Si las restauraciones no aparecen y quieres contarlas, el SDK de npm de Flowsery expone un método trackPageview() que puedes llamar desde un listener de pageshow que compruebe event.persisted, lo que evita el doble conteo que provocaría un listener sin esa comprobación.
Preguntas frecuentes
¿Todos los navegadores tienen bfcache?
Sí, todos los navegadores principales incluyen una. web.dev cita Chrome desde la versión 96, Firefox y Safari. Cada navegador tiene sus propias reglas de aptitud, y por eso la misma página puede guardarse en un navegador y recargarse en otro.
¿Una restauración desde la bfcache dispara el evento load?
No. Una restauración vuelve a hacer visible la página pausada y reanuda su JavaScript, así que load y DOMContentLoaded no se disparan. Se dispara el evento pageshow, con persisted a true.
¿Por qué bajaron mis páginas vistas cuando Chrome amplió la bfcache?
Más clics en atrás y adelante pasaron a ser restauraciones en lugar de recargas, y muchos scripts de analítica solo cuentan páginas vistas al cargar. web.dev describe exactamente esta caída. Añade un listener de pageshow que envíe una página vista cuando event.persisted valga true si quieres contar las restauraciones.
¿Cache-Control: no-store desactiva la bfcache?
En la propia página, históricamente ha dejado las páginas fuera de la bfcache. web.dev recomienda usarlo solo en páginas con información sensible, y usar no-cache o max-age=0 en las páginas que solo necesitan contenido actualizado. Ninguna de esas dos opciones afecta a la aptitud.
¿Cómo compruebo si una página es apta para la bfcache?
En Chrome DevTools, ve a Application, después a Back-forward Cache, y haz clic en Run Test. El panel indica si la página se restauró y, si no, lista los motivos del bloqueo. Para visitas reales, lee notRestoredReasons de la entrada de navigation timing.
¿La bfcache funciona dentro de una aplicación de una sola página?
No. web.dev afirma que la bfcache "doesn't work for 'soft navigations' within a single-page app." Se aplica cuando un visitante sale de la app y vuelve con el botón atrás, lo que puede restaurar la app entera en lugar de arrancarla desde cero si la página cumple los requisitos.
¿Qué pasa con los temporizadores y los heartbeats mientras una página está en la bfcache?
Los navegadores pausan los temporizadores pendientes y las promesas sin resolver, y los reanudan al restaurar. Un heartbeat o un temporizador de interacción continúa después del hueco, así que el tiempo que la página pasó en memoria no cuenta como interacción.
¿Un listener de unload deja una página fuera de la bfcache?
Sí, en Chrome y Firefox de escritorio, y en Firefox móvil salvo en iOS. Sustituye unload por pagehide y la página sigue siendo apta.
¿Cómo evito contar páginas vistas dos veces con un listener de pageshow?
pageshow se dispara en cada carga normal y en cada restauración, así que envía la página vista solo cuando event.persisted sea true. El arranque normal del tracker ya cubre la carga habitual. Después pulsa atrás en una página de prueba y comprueba que cada clic genera exactamente un registro.
¿Flowsery cuenta automáticamente las restauraciones desde la bfcache?
La documentación de Flowsery no lo describe, así que pruébalo en tu propio sitio. Abre una página, haz clic en un enlace, pulsa atrás y mira en la vista de analítica en tiempo real si aparece una página vista nueva. Si no aparece, llama a trackPageview() del SDK de npm dentro de un listener de pageshow que compruebe event.persisted.
¿Te resultó útil este artículo?
¡Cuéntanos qué opinas!
Vernos más en Google
Un clic marca Flowsery como fuente preferida y nuestros artículos aparecen más arriba en tus Noticias destacadas, el modo IA y los resúmenes con IA.
Antes de irte...
Flowsery
Analítica orientada a ingresos para tu sitio web
Rastrea cada visitante, fuente y conversión en tiempo real. Simple, potente y sin cookies.
Panel en tiempo real
Seguimiento de objetivos
Rastreo sin cookies
Términos relacionados del glosario
Cómo el tracking de SPA cuenta páginas vistas si la página nunca se recarga
Un buen tracking de SPA registra una página vista por pantalla con el referrer correcto. Cómo encajan la History API, las vistas virtuales y GA4.


Por qué tu tasa de rebote de GA4 es la tasa de interacción al revés
Google mide la tasa de rebote de GA4 como la proporción de sesiones sin interacción. Cómo la define, en qué difiere de Universal Analytics y dónde añadirla.


Qué cuenta el informe de páginas de destino de GA4 y dónde se queda en blanco
En Reports, el informe de páginas de destino de GA4 lista la primera página de cada sesión. Dónde está, sus métricas, por qué sale (not set) y la fuente.


Cómo registra la búsqueda en el sitio de GA4 lo que escriben los visitantes
Configura la búsqueda en el sitio de GA4 con la medición mejorada, añade tus parámetros de consulta, halla la dimensión Search term y mide sin URL.


Cómo definir propiedades de usuario de GA4 y usarlas en informes
Define propiedades de usuario de GA4 con gtag o Tag Manager, regístralas como dimensiones personalizadas de usuario y no pases del límite de 25.


Cómo vincular Search Console con GA4 y publicar sus informes
Aprende a vincular Search Console con GA4 en Admin, qué roles necesitas, cómo publicar los dos informes en Library y qué datos no se pueden cruzar.
Artículos relacionados


Qué fue de la retirada de las cookies de terceros en Chrome
En Chrome, la retirada de las cookies de terceros fue de un plan en 2020 a una marcha atrás en 2025. Cada anuncio de Google, qué hace Chrome hoy y qué implica.


Por qué el CNAME cloaking ya no oculta rastreadores a Safari ni a Brave
Los rastreadores usaban el CNAME cloaking para pasar por tu subdominio. Mira el truco DNS, el límite de 7 días de Safari y cómo Brave y uBlock lo destapan.


Cómo la sincronización de cookies empareja IDs publicitarios entre sitios
El ad-tech usa la sincronización de cookies para intercambiar IDs con redirecciones y píxeles. Mira qué hacen Safari, Firefox y Chrome al respecto.

