Caché de atrás/adelante (bfcache)

Qué es la caché de atrás/adelante: la función del navegador que congela una página entera en memoria para permitir una navegación instantánea con Atrás/Adelante; en qué se diferencia de la caché HTTP, qué impide la aptitud, cómo probarla y cuál es su relación real e indirecta con los Core Web Vitals y el SEO.

Publicado por primera vez: 3 jul 2026 · Última actualización: 8 ago 2026 · Avanzado
Idiomas

La caché de atrás/adelante (bfcache) es una optimización del navegador que congela una página entera —DOM, heap de JavaScript y estado en ejecución— en memoria al navegar fuera de ella, de modo que Atrás o Adelante puede restaurarla al instante sin recarga, sin volver a renderizar y sin solicitudes de red, siempre que el navegador no haya expulsado antes esa instantánea congelada. Es una función del navegador, no un factor de posicionamiento: la documentación de Google sobre el posicionamiento mediante Core Web Vitals ni siquiera la menciona. Su relevancia para SEO es indirecta y acotada: una navegación restaurada desde bfcache registra un LCP casi instantáneo y un CLS prácticamente igual a cero para las personas que la reciben, lo que puede mejorar los Core Web Vitals de campo agregados en un sitio con tráfico significativo de Atrás/Adelante (1 de cada 10 navegaciones de escritorio y 1 de cada 5 en móvil), pero no garantiza tu tasa de restauración, tu valoración global de CWV, tus posiciones ni la conversión. El mayor bloqueo individual es el controlador del evento unload; históricamente el mayor fue Cache-Control: no-store, aunque Chrome permite ahora bfcache en muchas páginas no-store de forma condicional desde su despliegue de 2025. Prueba casos aislados con Chrome DevTools o usa la API notRestoredReasons, exclusiva de Chrome, para datos de campo. No confundas bfcache con la caché HTTP, la caché de recursos en memoria del navegador, Cache Storage de un service worker ni la antigua función de búsqueda de «página almacenada» ya retirada.

TL;DR — Bfcache es una instantánea de la página completa en memoria (DOM + heap de JS + estado en ejecución), no una respuesta HTTP que se pueda volver a solicitar, ni la caché de recursos en memoria del navegador, ni Cache Storage de un service worker: esa es la distinción conceptual número uno. Al navegar fuera, el navegador pausa JavaScript y congela la página; al pulsar Atrás/Adelante, si esa instantánea sigue disponible, la descongela y la vuelve a mostrar al instante, sin solicitudes de red, pero siempre es posible que la expulse, así que trata la restauración como probable, no garantizada. No es un factor de posicionamiento documentado por Google Search (la documentación de Core Web Vitals de Search Central no la menciona); su relevancia es indirecta y acotada, a través de la medición de CWV de campo (principalmente LCP y CLS) en las navegaciones que sí se restauran: no garantiza tu tasa de restauración, tu valoración global de CWV, tus posiciones ni la conversión. El mayor bloqueo de aptitud es el controlador unload (aproximadamente 18 puntos porcentuales de la tasa de restauración en Chrome); históricamente el mayor fue Cache-Control: no-store (bloqueaba aproximadamente el 17 % de las navegaciones históricas en móvil y el 7 % en escritorio), aunque Chrome permite ahora bfcache en muchas páginas no-store de forma condicional (las expulsa si cambian la autenticación o las cookies y las mismas API de conexiones abiertas siguen bloqueándolas) tras su despliegue de 2025. Las conexiones abiertas, los temporizadores y los observers deben cerrarse o pausarse en pagehide/freeze y restablecerse en pageshow/resume; window.opener, las políticas de permisos y los frames también pueden bloquearla: comprueba el motivo por frame en DevTools o notRestoredReasons en lugar de suponerlo. Prueba casos aislados con Chrome DevTools y diagnostica en campo con la API notRestoredReasons, exclusiva de Chrome (un resultado null no demuestra una restauración y el texto del motivo no es estable). Cada navegador tiene sus propias reglas de aptitud, y las navegaciones blandas de las SPA no reciben el mismo tratamiento.

Evidence for this claim The back-forward cache stores a complete page snapshot for instant history navigation. Scope: Current official or standards documentation. Confidence: high · Verified: web.dev: Back/forward cache Evidence for this claim Browser eligibility rules and APIs such as unload handlers can prevent bfcache use. Scope: Current official or standards documentation. Confidence: high · Verified: web.dev: bfcache eligibility

Qué es realmente bfcache (la columna vertebral de precisión)

Lo más importante que hay que entender bien es esto: bfcache es una instantánea de la página completa en memoria, no una respuesta HTTP guardada. Cuando navegas fuera de una página, el navegador no la desmonta: pausa la ejecución de JavaScript y congela la página entera —el DOM, el heap de JS, los temporizadores en curso, todo— y la mantiene en memoria. Si pulsas Atrás o Adelante mientras esa instantánea congelada aún está disponible, la descongela y vuelve a mostrar exactamente la página que dejaste, con cero solicitudes de red y cero renderizado de nuevo. Es una restauración posible, no una garantía: el navegador puede expulsar la instantánea antes de que vuelvas (por presión de memoria, un tiempo de espera o ciertos eventos), o una regla del navegador puede forzar una carga nueva; en ese caso solo es una navegación histórica normal. El encuadre canónico de Google es que bfcache es “a browser optimization that enables instant back and forward navigation.” (traducción) «una optimización del navegador que permite una navegación instantánea hacia atrás y hacia adelante».

Por eso confundirla con la caché HTTP o del navegador es el error recurrente de la competencia. La caché HTTP guarda respuestas a solicitudes anteriores: archivos que puede volver a servir. Bfcache guarda la página viva y en ejecución. La documentación de Chrome DevTools marca explícitamente la diferencia: bfcache “differs from browser cache and HTTP cache.” (traducción) «se diferencia de la caché del navegador y de la caché HTTP». No «activas» bfcache con cabeceras de caché como configuras la caché HTTP; el único lugar donde entran las cabeceras es que Cache-Control: no-store solía descalificar una página (volveremos a ello).

La misma distinción se aplica frente a otras dos cachés que a veces se confunden con bfcache: la caché de recursos en memoria del navegador (scripts compilados e imágenes decodificadas conservados durante la sesión actual) y Cache Storage de un service worker (pares explícitos de solicitud/respuesta que el sitio administra mediante caches.open()). Ambas pueden estar activas en la misma página que bfcache al mismo tiempo; ninguna es bfcache, que es específicamente la instancia de página congelada, no assets guardados ni respuestas interceptadas.

Hay otra aclaración que conviene hacer porque sigue causando confusión: bfcache no tiene nada que ver con la antigua función de búsqueda de «página almacenada» que Google (y Bing) mostraba antes en los resultados. Era una instantánea guardada de una página en el índice de búsqueda y se retiró. Bfcache es una función del motor de renderizado del lado del cliente.

¿Son frecuentes de verdad las navegaciones Atrás/Adelante?

No es un caso extremo. Según web.dev, “1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward.” (traducción) «1 de cada 10 navegaciones en escritorio y 1 de cada 5 en móvil son hacia atrás o hacia adelante». En cualquier sitio con recorridos repetidos de Atrás/Adelante —categoría a producto y vuelta en comercio electrónico, resultados de búsqueda, contenido paginado o lectura de artículo a artículo— es una porción grande de navegaciones reales que puedes hacer casi instantáneas.

Compatibilidad de los navegadores

“All major browsers include a bfcache, including Chrome since version 96, Firefox and Safari.” (traducción) «Los principales navegadores incluyen bfcache, incluidos Chrome desde la versión 96, Firefox y Safari». Firefox y Safari tienen sus propias implementaciones de bfcache, más antiguas; todos los navegadores basados en Chromium (Edge, Brave, Opera y Arc) heredan la de Chrome. La documentación de políticas de Microsoft Edge describe la misma función: al navegar fuera de una página, su estado actual (árbol del documento, script y demás) puede conservarse en la caché de atrás/adelante y, si el navegador vuelve a ella, puede restaurarse desde allí y mostrarse en el estado que tenía antes de guardarse. Viene activada de forma predeterminada en Edge; el único interruptor de apagado es una política empresarial que controla el administrador de TI, no el propietario del sitio.

La salvedad importante es que cada navegador aplica sus propias reglas de aptitud para bfcache. Que una página supere la prueba «Test back/forward cache» de Chrome DevTools no garantiza que sea apta en Firefox o Safari. Trata un aprobado de Chrome como necesario, no suficiente.

Qué impide la aptitud para bfcache

El evento unload: el mayor bloqueo individual

Si solo te quedas con una cosa de este artículo, que sea esta: deja de usar el evento unload. web.dev lo expresa con un énfasis poco habitual para un documento de Google: “Never use the unload event. Ever!” (traducción) «No uses nunca el evento unload. ¡Nunca!». En Chrome, los controladores de unload cuestan aproximadamente una reducción de 18 puntos porcentuales en la tasa de restauración de bfcache, el mayor descalificador que puedes introducir tú mismo.

Hay dos motivos por los que Chrome lo está retirando activamente. Primero, es el mayor bloqueo de bfcache. Segundo, unload ya es extremadamente poco fiable: en móvil con frecuencia ni siquiera se ejecuta, porque las pestañas pasan a segundo plano, se eliminan y el navegador prioriza bfcache frente a disparar unload. Así que el evento del que dependes para la «limpieza» a menudo no se ejecuta y bloquea una mejora real de rendimiento.

Las correcciones:

  • Sustituye unload por pagehide. El evento pagehide se dispara en todos los casos en que lo haría unload y además cuando una página entra en bfcache: es una mejora estricta. Usa visibilitychange para la limpieza fiable cuando la persona se va.
  • Detecta una restauración de bfcache con pageshow. Escucha pageshow y comprueba event.persisted; si es true, la página se restauró desde bfcache, la señal para actualizar datos obsoletos o volver a contar una visita.
  • Bloquea de forma preventiva los listeners de unload con la cabecera de respuesta Permissions-Policy: unload=(), que impide registrar cualquier controlador unload. Chrome está trasladando gradualmente la política predeterminada hacia la denegación (una Permissions-Policy para unload se lanzó desde Chrome 115).

Cache-Control: no-store: históricamente el mayor, ahora con matices

Este es el punto de frescura que más equivocadamente trata el contenido de la competencia. Históricamente, Cache-Control: no-store era el motivo individual más importante por el que se excluían páginas de bfcache: las cifras de Chrome lo situaban aproximadamente en el 17 % de las navegaciones históricas en móvil y el 7 % en escritorio. Muchos sitios configuran no-store de forma defensiva para evitar servir una página obsoleta, pero el argumento de Google es que esa razón pierde fuerza con bfcache: una restauración de bfcache no carga una respuesta guardada obsoleta, sino que vuelve a mostrar la página viva exacta casi como si la pestaña se hubiera quedado abierta.

Por eso Chrome cambió el comportamiento, pero de forma condicional, no universal. Los experimentos comenzaron en Chrome 116, con el despliegue final al 100 % de las personas durante marzo y abril de 2025: Chrome permite ahora bfcache en muchas páginas no-store, sujeto a condiciones de seguridad concretas en vez de una excepción general. Según la documentación de Chrome, existen límites reales: la página se expulsa de bfcache si cambia el estado de autenticación o las cookies mientras está congelada (para que una persona que ha cerrado sesión o borrado cookies no vea una instantánea antigua con sesión abierta), y una lista fija de API —las mismas API de conexiones abiertas que se tratan abajo (IndexedDB, WebSocket, WebRTC y demás)— sigue excluyendo de bfcache una página no-store igual que cualquier otra. Es un comportamiento específico de Chrome y de un intervalo concreto de versiones, no una regla que puedas suponer para otros navegadores o versiones antiguas de Chrome: consulta el informe actual de DevTools/notRestoredReasons para el navegador y la versión que realmente estés probando, en vez de confiar en una regla fija.

Conclusión práctica: cualquier guía (incluidas las versiones antiguas de esta) que enumere no-store como bloqueo incondicional y permanente de bfcache está obsoleta, pero también lo está tratarlo como un problema completamente resuelto. Si la frescura importa de verdad, la documentación de Chrome sugiere no-cache o un max-age breve (por ejemplo, max-age=60) en lugar de no-store.

Conexiones abiertas, observers y otros bloqueos

En el momento de navegar, ciertos recursos abiertos todavía pueden impedir la aptitud, y exactamente cuáles lo hacen —y si bloquean por completo o simplemente se cierran y se pueden reconectar— depende del navegador y de su versión. Trata la lista siguiente como ejemplos de un patrón, no como una lista fija y permanente:

  • Solicitudes fetch() / XMLHttpRequest en curso.
  • Transacciones abiertas de IndexedDB.
  • Conexiones abiertas de WebSocket / WebRTC, temporizadores y observers (MutationObserver, IntersectionObserver y similares). Es un área que mejora activamente: las notas de lanzamiento recientes de Microsoft Edge muestran que un WebSocket abierto ahora se cierra cuando una página entra en bfcache (en vez de bloquear la caché por completo), con la reconexión recomendada mediante el evento pageshow y su comprobación event.persisted. Eso refleja la tendencia más amplia de Chrome a reducir bloqueos en lugar de excluir páginas sin más.

El patrón general que conviene implementar, en vez de memorizar una lista fija, es cerrar o pausar las conexiones abiertas, los temporizadores y los observers al gestionar pagehide/freeze, y restablecerlos al gestionar pageshow/resume cuando event.persisted sea true. Ese patrón resiste que un navegador cambie qué API bloquea la aptitud por completo y cuál simplemente suspende para que puedas reconectarla.

window.opener, políticas de permisos y frames. Una referencia window.opener, ciertas políticas de permisos y frames incrustados (del mismo origen o de otro) también pueden afectar a la aptitud; es algo que resumí en la guía de CLS de Ahrefs y en la documentación de Chrome. Pero no supongas la causa real a partir de una lista genérica: el panel de Chrome DevTools y la API notRestoredReasons informan de los motivos de bloqueo por frame —el frame superior y cada iframe por separado—, porque el frame responsable no siempre es la página de nivel superior. Obtén el motivo real del informe de ese frame para el navegador que estés probando, en lugar de adivinar a partir de una lista general.

Cómo acertar con la secuencia de eventos y estados del ciclo de vida

Confundir lo que cada evento del ciclo de vida realmente demuestra con lo que solo sugiere es el segundo error de corrección más común aquí, después de los errores de aptitud anteriores:

Evento / estadoSeñalLo que significa realmenteQué hacer
pagehide (event.persisted === true)Intención de guardar en cachéEl navegador intenta congelar la página para bfcache; no es una entrada confirmada en cachéCerrar o pausar conexiones, temporizadores y observers aquí; no suponer que la página se restaurará
freezeEn pausaLa ejecución de JS está pausada; la página aún puede ser expulsada antes de una restauraciónNada aparte de lo que ya hiciste en pagehide
(sin evento) posible expulsiónEl navegador puede borrar una página congelada de la memoria en cualquier momento —presión de memoria, tiempo de espera o una regla del navegador— y no hay ningún evento que se dispare para avisarloNo depender de que el código de limpieza se ejecute después; hacerlo sin condiciones en pagehide/freeze
pageshow (event.persisted === true)Restauración confirmadaLa única señal fiable de que realmente ocurrió una restauración desde bfcacheActualizar el estado sensible al tiempo, reconectar conexiones cerradas y contar exactamente una visita analítica
resumeReanudadoLa ejecución de JS deja de estar pausada después de una restauración confirmadaReconectar lo que se pausó en freeze

La regla práctica es tratar pagehide.persisted como intención, no como prueba: la página todavía puede ser expulsada antes de que veas una restauración. Solo pageshow.persisted === true demuestra que ocurrió. Haz la limpieza sin condiciones en pagehide/freeze (es barata y segura incluso en una navegación normal) y ejecuta el trabajo específico de restauración solo en pageshow/resume, condicionado a event.persisted, para no actualizar datos ni contar dos veces una visita en una carga nueva normal.

Cómo probar y diagnosticar bfcache

Laboratorio / caso aislado: Chrome DevTools

Abre DevTools → Application → Background services → Back/forward cache y haz clic en «Test back/forward cache». Chrome navega automáticamente a chrome://terms/ y vuelve, y después informa de éxito o de una lista concreta de motivos de bloqueo. Es útil para comprobar una URL cada vez.

Campo / producción: la API notRestoredReasons

Antes, la única forma de comprobar la aptitud era esa prueba manual de DevTools, una URL cada vez; no había forma de saber por qué se bloqueaban las navegaciones de personas reales. La propiedad notRestoredReasons de PerformanceNavigationTiming (disponible desde Chrome 123+) cierra esa brecha: informa de los motivos de bloqueo concretos del frame superior y de los iframes del mismo origen en datos de campo reales.

const nav = performance.getEntriesByType('navigation')[0];
console.log(nav.notRestoredReasons);

Al usarla, hay algunos puntos importantes que vienen directamente de la guía de la API de Chrome:

  • Solo funciona en Chrome (123+). Firefox y Safari no exponen un campo equivalente, así que necesitarás comprobaciones manuales en esos navegadores para conocer allí tu tasa de restauración.
  • Un resultado null es ambiguo, no una luz verde. Puede significar que la página se restauró o que el navegador simplemente no recopiló un motivo; la propia documentación de Chrome dice que no se debe tratar null como prueba de una restauración correcta.
  • El texto del motivo no es un contrato estable. No codifiques coincidencias contra sus cadenas; agrupa y sigue la tendencia por motivo porque las palabras exactas pueden cambiar entre versiones de Chrome.

En la práctica, extrae notRestoredReasons junto con las tasas de restauración de pageshow.persisted antes y después de publicar una corrección, compara la tendencia en vez de una instantánea y acompáñala de una prueba manual de laboratorio en Firefox y Safari, los navegadores a los que no llega la API. Es la herramienta adecuada para diagnosticar bfcache a escala en RUM/producción, en vez de comprobar URL por URL; solo no la trates como el panorama completo.

Bfcache y Core Web Vitals: la relación precisa

Este es el matiz que más difumina el contenido de la competencia y el ángulo que merece la pena explicar con precisión.

Cómo se mide una restauración de bfcache. Los navegadores (y, por tanto, los datos de campo de CrUX) cuentan una navegación restaurada desde bfcache como una «carga de página» extremadamente rápida: un LCP casi instantáneo y, cuando la página está implementada correctamente (no tiene que redistribuir el diseño), un CLS adicional prácticamente igual a cero, porque no hay un renderizado de nuevo. En la comparación del mundo real de DebugBear, una página restaurada desde bfcache obtuvo un LCP de alrededor de 100 ms frente a unos 427 ms en una carga sin caché. Por eso bfcache aparece como palanca para CLS y LCP en mi propia lista de comprobación de CLS de Ahrefs, donde lo resumo así: “Make sure your pages are eligible for bfcache. The back/forward cache keeps pages in the browser cache. It allows for instant loading of a page that was already loaded, meaning no layout shifts will happen.” (traducción) «Comprueba que tus páginas pueden entrar en bfcache. El mecanismo conserva en la caché del navegador una página ya cargada. Hace posible mostrarla al instante, así que no se producen cambios de diseño».

Hay dos salvedades de alcance que conviene expresar con precisión porque aquí el contenido de la competencia suele exagerar. Primero, esto solo afecta a las navegaciones que CrUX clasifica como atrás/adelante (su dimensión navigation-type): no dice nada de las navegaciones de primera visita o de recarga, que son la mayoría del tráfico en la mayoría de los sitios. Segundo, que una restauración mejore la experiencia medida de quienes la reciben no equivale a una garantía: quien haya sido expulsado de bfcache (consulta la tabla del ciclo de vida) obtiene una carga normal, sin mejora; por tanto, el trabajo de aptitud para bfcache mueve tu tasa de restauración entre las navegaciones Atrás/Adelante, no un porcentaje fijo de todo tu tráfico, y no garantiza tu valoración global de Core Web Vitals de campo, tus posiciones ni tu tasa de conversión. Es una palanca real y medible con un alcance concreto, no una solución general de rendimiento o SEO.

¿Es bfcache un factor de posicionamiento? No. Esta es la afirmación defendible y diferenciadora. La propia documentación de Google sobre el posicionamiento mediante Core Web Vitals no menciona bfcache. La cadena de influencia honesta es: aptitud para bfcache → mejores cifras de CWV de campo (principalmente LCP/CLS) en navegaciones Atrás/Adelante → Core Web Vitals es una señal entre muchas de «experiencia de página» que Google dice que encajan con lo que ya premian sus sistemas de posicionamiento. Es una afirmación materialmente más débil y precisa que «bfcache mejora las posiciones», y es la que el contenido de la competencia debería hacer pero normalmente no formula con cuidado. Bfcache es también, correctamente, una función del motor de renderizado, no del crawler: no tiene nada que ver con cómo Googlebot o Bingbot rastrean tus páginas, por eso no existe un «punto de vista de Bing sobre bfcache para SEO» como sí lo hay para robots.txt o sitemaps.

SPA y navegaciones blandas. Bfcache funciona con navegaciones y eventos de historial reales del navegador. El cambio de ruta «blando» de una aplicación de una sola página (un intercambio de vista dirigido por JS que no activa una navegación real del navegador) no es un evento de bfcache ni recibe el mismo tratamiento. Los intentos de algunas herramientas RUM de atribuir Core Web Vitals a navegaciones blandas pueden crear diferencias de medición entre CrUX y RUM; conviene señalarlo al auditar un sitio basado en un framework JS.

¿Qué frecuencia tienen los bloqueos de bfcache en la práctica?

El Web Almanac de HTTP Archive lo registra, y es un área viva y cambiante, no una noticia antigua ya cerrada. En la edición de 2022, al menos alrededor del 22 % de las páginas móviles no eran aptas para bfcache solo por los criterios de unload y no-store. Desde entonces, el uso de controladores unload ha disminuido entre niveles de sitios y dispositivos, pero el uso de Cache-Control: no-store ha aumentado (el capítulo de 2025 lo sitúa alrededor del 23 % de los sitios, frente a aproximadamente el 21 % en 2024, en parte por el aumento de experiencias autenticadas o personalizadas y requisitos de cumplimiento más estrictos).

El hallazgo contraintuitivo que merece citarse es que los sitios grandes y con más tráfico tienen desproporcionadamente más probabilidades de bloquear su propia bfcache. Entre los 1 000 sitios principales, aproximadamente el 28 % de las páginas de escritorio y el 20 % de las móviles siguen usando controladores unload, frente a solo alrededor del 11 % en escritorio y el 10 % en móvil de todos los sitios, a menudo porque los sitios grandes arrastran más analítica heredada y código dependiente de unload. Los sitios que tienen más tráfico de Atrás/Adelante que perder suelen ser los que más se estorban a sí mismos.

Dónde encaja

Bfcache es una palanca de rendimiento entre varias de este clúster. Su beneficio aparece en los datos de campo de Core Web Vitals, específicamente en Cumulative Layout Shift y Largest Contentful Paint, porque una página restaurada vuelve a mostrarse al instante sin redistribuir el diseño. Es distinta de la caché, que guarda archivos y no una instantánea de página viva, aunque ambas comparten la cabecera Cache-Control como punto de contacto. No existe un vínculo directo con Interaction to Next Paint, así que no voy a forzarlo.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.