Cache de Voltar/Avançar (bfcache)

O que é o cache de voltar/avançar — o recurso do navegador que congela uma página inteira na memória para permitir navegação instantânea —, como ele difere do cache HTTP, o que bloqueia a elegibilidade, como testá-lo e sua relação real (indireta) com Core Web Vitals e SEO.

Publicado pela primeira vez: 3 de jul. de 2026 · Última atualização: 11 de ago. de 2026 · Avançado
Idiomas

O cache de voltar/avançar (bfcache) é uma otimização do navegador que congela uma página inteira — DOM, heap de JavaScript e estado em execução — na memória quando você sai dela, para que Voltar ou Avançar possa restaurá-la instantaneamente, sem recarregamento, nova renderização ou requisições de rede, desde que o navegador não remova primeiro aquele snapshot congelado. É um recurso do navegador, não um fator de ranqueamento: a própria documentação de ranqueamento dos Core Web Vitals do Google nunca menciona bfcache. Sua relevância para SEO é indireta e limitada — uma navegação restaurada pelo bfcache produz LCP quase instantâneo e CLS efetivamente zero para os usuários que a obtêm, o que pode melhorar os Core Web Vitals de campo agregados em sites com tráfego significativo de Voltar/Avançar (1 em cada 10 navegações no desktop e 1 em cada 5 no mobile), mas não garante sua taxa de restauração, sua avaliação geral de CWV, rankings ou conversão. O maior bloqueador individual é o handler de unload; historicamente, o maior era Cache-Control: no-store, embora o Chrome agora permita bfcache condicionalmente para muitas páginas no-store após o lançamento de 2025. Teste com o Chrome DevTools para verificações pontuais de laboratório ou use a API notRestoredReasons, exclusiva do Chrome, para dados de campo. Não confunda bfcache com o cache HTTP, o cache de recursos em memória do navegador, o Cache Storage de um service worker ou o antigo recurso de busca de página em cache, hoje aposentado.

TL;DR — O bfcache é uma captura da página inteira em memória (DOM + memória dinâmica do JS + estado em execução), não uma resposta HTTP que possa ser buscada novamente, nem o cache de recursos em memória do navegador, nem o Cache Storage de um service worker — essa é a principal distinção conceitual. Ao sair, o navegador pausa o JS e congela a página; ao usar Voltar/Avançar, se aquela captura congelada ainda estiver disponível, ele a descongela e exibe novamente de imediato, com zero requisições de rede — mas a remoção é sempre possível, então trate uma restauração como provável, não garantida. Ele não é um fator de ranqueamento documentado da Busca do Google (a documentação de Core Web Vitals do Search Central nunca o menciona); sua relevância é indireta e limitada, por meio da medição de CWV em campo (principalmente LCP e CLS) nas navegações que são restauradas — ele não garante sua taxa de restauração, sua avaliação agregada de CWV, rankings ou conversões. O maior bloqueador de elegibilidade é o handler de unload (cerca de 18 pontos percentuais da taxa de sucesso no Chrome); historicamente, o maior era Cache-Control: no-store (bloqueando cerca de 17% das navegações de histórico mobile / 7% das desktop), embora o Chrome agora permita bfcache condicionalmente para muitas páginas no-store (removidas quando há mudança de autenticação/cookies, ainda bloqueadas pelas mesmas APIs de conexão aberta) após o lançamento de 2025. Conexões abertas, timers e observers devem ser fechados/pausados em pagehide/freeze e reestabelecidos em pageshow/resume; window.opener, políticas de permissões e frames também podem bloqueá-lo — confira o motivo por frame no DevTools ou em notRestoredReasons em vez de presumir. Faça testes pontuais com o Chrome DevTools; diagnostique em campo com a API notRestoredReasons exclusiva do Chrome (um resultado null não prova uma restauração, e o texto do motivo não é estável). Cada navegador tem suas próprias regras de elegibilidade, e navegações suaves de SPAs não recebem o mesmo tratamento.

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

O que o bfcache realmente é (a espinha dorsal da precisão)

O ponto mais importante a acertar: bfcache é uma captura da página inteira em memória, não uma resposta HTTP armazenada em cache. Quando você sai de uma página, em vez de destruí-la, o navegador pausa a execução do JavaScript e congela a página inteira — o DOM, a memória dinâmica do JS, os temporizadores em andamento, tudo — e a mantém na memória. Se você pressionar Voltar ou Avançar enquanto a captura congelada ainda estiver disponível, o navegador a descongela e exibe novamente a página exata que você deixou, com zero requisições de rede e zero novo leiaute. É uma restauração possível, não uma garantia — o navegador pode remover a captura antes que você volte (pressão de memória, tempo limite, certos eventos), ou uma regra específica do navegador pode forçar um carregamento novo; nesse caso, trata-se apenas de uma navegação comum pelo histórico.

A formulação canônica do Google resume o mecanismo desta forma: “a browser optimization that enables instant back and forward navigation.” (tradução) «uma otimização do navegador que torna instantâneas as navegações de Voltar e Avançar». É por isso que confundi-lo com o cache HTTP/do navegador é o erro recorrente dos concorrentes. O cache HTTP armazena respostas a requisições anteriores — arquivos que pode servir novamente. O bfcache armazena a página viva em execução. A documentação do Chrome DevTools traça a distinção explicitamente: o bfcache “differs from browser cache and HTTP cache.” (tradução) «não é igual ao cache do navegador nem ao cache HTTP». Você não “liga” o bfcache com cabeçalhos de cache da mesma forma que configura o cache HTTP — o único ponto em que os cabeçalhos entram é que Cache-Control: no-store costumava desqualificar uma página (mais sobre isso abaixo).

A mesma distinção vale para outros dois caches que as pessoas às vezes confundem com o bfcache: o cache de recursos em memória do navegador (scripts compilados e imagens decodificadas mantidos na sessão atual) e o Cache Storage de um service worker (pares explícitos de requisição/resposta que o site gerencia por meio de caches.open()). Ambos podem estar ativos na mesma página ao mesmo tempo que o bfcache — nenhum deles é o bfcache, que é especificamente a instância congelada da página, e não ativos armazenados ou respostas interceptadas.

Mais uma distinção vale ser feita porque ainda causa confusão: o bfcache não tem nada a ver com o antigo recurso de busca “página em cache” que Google (e Bing) já exibiram nos resultados. Aquilo era um snapshot armazenado de uma página no índice de busca e foi aposentado. O bfcache é um recurso do mecanismo de renderização no lado do cliente.

Quão comuns são as navegações de Voltar/Avançar, de verdade?

Este não é um caso extremo de nicho. Segundo o web.dev, “1 in 10 navigations on desktop and 1 in 5 on mobile are either back or forward.” (tradução) «1 em cada 10 navegações no desktop e 1 em cada 5 no mobile são de Voltar ou Avançar». Em qualquer site com fluxos repetidos de voltar/avançar — categoria para produto e volta no e-commerce, resultados de busca, conteúdo paginado, leitura de artigo para artigo — isso representa uma grande parcela de navegações reais que você pode tornar quase instantâneas.

Suporte dos navegadores

“All major browsers include a bfcache, including Chrome since version 96, Firefox and Safari.” (tradução) «Todos os principais navegadores incluem um bfcache, entre eles o Chrome desde a versão 96, o Firefox e o Safari.» O Firefox e o Safari têm suas próprias implementações de bfcache, mais antigas e duradouras; todos os navegadores baseados em Chromium (Edge, Brave, Opera, Arc) herdam o comportamento do Chrome. A documentação da política do Edge da Microsoft descreve o mesmo recurso: ao sair de uma página, seu estado atual (árvore do documento, script e assim por diante) pode ser preservado no cache de voltar/avançar; se o navegador voltar à página, ela poderá ser restaurada a partir dele e exibida no estado em que estava antes de ser armazenada. Ele vem ativado por padrão no Edge; o único interruptor é uma política corporativa controlada por um administrador de TI, não pelo proprietário do site.

A ressalva importante: o bfcache de cada navegador aplica suas próprias regras de elegibilidade. Uma página aprovada no teste Test back/forward cache (tradução) «Testar cache de Voltar/Avançar» do Chrome DevTools não tem elegibilidade garantida no Firefox ou no Safari. Trate uma aprovação no Chrome como necessária, não suficiente.

O que bloqueia a elegibilidade do bfcache

O evento unload — o maior bloqueador individual

Se você guardar uma coisa deste artigo, que seja: pare de usar o evento unload. O web.dev dá a isso uma ênfase rara para um documento do Google: “Never use the unload event. Ever!” (tradução) «Nunca use o evento unload. Em hipótese alguma!» No Chrome, handlers de unload custam aproximadamente uma redução de 18 pontos percentuais na taxa de sucesso do bfcache — de longe o maior desqualificador autoinfligido.

Há duas razões para o Chrome estar descontinuando-o ativamente. Primeiro, ele é o maior bloqueador do bfcache. Segundo, unload já é extremamente pouco confiável: no mobile, frequentemente não dispara de modo algum, porque as abas vão para segundo plano e são encerradas, e o navegador prioriza o bfcache em vez de disparar unload. Portanto, o evento em que você confia para “limpeza” muitas vezes não executa e está bloqueando um ganho real de desempenho.

As correções:

  • Substitua unload por pagehide. O evento pagehide dispara em todos os casos em que unload dispara, além de quando uma página entra no bfcache — é uma melhoria estrita. Use visibilitychange para uma limpeza confiável quando o “usuário está saindo”.
  • Detecte uma restauração do bfcache com pageshow. Escute pageshow e verifique event.persisted — se for true, a página foi restaurada do bfcache, o que indica que você deve atualizar dados antigos ou recontar uma visualização de página.
  • Bloqueie proativamente listeners de unload com o cabeçalho de resposta Permissions-Policy: unload=(), que impede que qualquer handler de unload seja registrado. O Chrome está migrando gradualmente a política padrão para negar (uma Permissions-Policy para unload foi lançada no Chrome 115).

Cache-Control: no-store — historicamente o maior, agora com nuances

Este é o ponto de atualização que a maior parte do conteúdo concorrente erra. Historicamente, Cache-Control: no-store era o maior motivo individual para páginas serem excluídas do bfcache — os números do próprio Chrome o colocam em aproximadamente 17% das navegações de histórico no mobile e 7% no desktop. Muitos sites definem no-store defensivamente para evitar servir uma página antiga, mas o argumento do Google é que essa justificativa perde força com bfcache: uma restauração do bfcache não carrega uma resposta antiga armazenada, e sim exibe novamente a página viva exata, quase como se a aba tivesse permanecido aberta.

Então o Chrome mudou o comportamento — mas condicionalmente, não de forma universal. Os experimentos começaram no Chrome 116, com o lançamento final para 100% dos usuários durante março e abril de 2025: agora o Chrome permite bfcache para muitas páginas no-store, sujeito a condições específicas de segurança em vez de uma exceção geral. Segundo a documentação do próprio Chrome, há restrições reais — a página é removida do bfcache se o estado de autenticação ou os cookies mudarem enquanto ela está congelada (assim, um visitante que saiu da conta ou limpou cookies não vê um snapshot antigo de sessão autenticada), e uma lista fixa de APIs — as mesmas APIs de conexão aberta tratadas abaixo (IndexedDB, WebSocket, WebRTC e as demais) — ainda exclui uma página no-store do bfcache da mesma forma que excluiria qualquer outra página. Esse é um comportamento específico do Chrome em uma faixa específica de versões, não uma regra que você possa presumir em outros navegadores ou versões antigas do Chrome — obtenha o relatório atual do DevTools/notRestoredReasons para o navegador e a versão que está testando, em vez de confiar em uma regra fixa. Conclusão prática: qualquer guia (inclusive versões antigas deste artigo) que liste no-store como bloqueador incondicional e permanente do bfcache está desatualizado — assim como tratar o problema como totalmente resolvido. Se a atualização realmente importa para uma página, a documentação do Chrome sugere no-cache ou um max-age curto (por exemplo, max-age=60), em vez de no-store.

Conexões abertas, observers e outros bloqueadores

No momento da navegação, determinados recursos abertos ainda podem bloquear a elegibilidade — e exatamente quais são esses recursos, e se bloqueiam de vez ou apenas são fechados e podem ser reconectados, depende do navegador e da versão. Trate a lista abaixo como exemplos de um padrão, não como uma lista fixa e permanente de bloqueadores:

  • Requisições fetch()/XMLHttpRequest em andamento.
  • Transações abertas de IndexedDB.
  • Conexões WebSocket/WebRTC abertas, timers e observers (MutationObserver, IntersectionObserver e similares). Esta área está evoluindo: notas de versão recentes do Microsoft Edge mostram que um WebSocket aberto agora é fechado quando uma página entra no bfcache (em vez de bloquear o armazenamento de forma direta), com reconexão recomendada pelo evento pageshow e pela verificação de event.persisted. Isso reflete a tendência mais ampla do Chrome de reduzir bloqueadores em vez de simplesmente excluir páginas.

O padrão geral a implementar, em vez de memorizar uma lista fixa: feche ou pause conexões abertas, timers e observers no tratamento de pagehide/freeze e restabeleça-os no tratamento de pageshow/resume quando event.persisted for true. Esse padrão continua válido mesmo que um navegador mude exatamente quais APIs bloqueiam a elegibilidade de forma direta e quais ele apenas suspende, permitindo reconexão.

window.opener, políticas de permissões e frames. Uma referência a window.opener, determinadas políticas de permissões e iframes incorporados (da mesma origem ou de origem cruzada) também podem afetar a elegibilidade — isso aparece no checklist que extraí do guia de CLS da Ahrefs e na documentação do Chrome. Mas não presuma a causa real a partir de um checklist genérico: o painel do Chrome DevTools e a API notRestoredReasons informam os motivos de bloqueio por frame — o frame superior e cada iframe separadamente — porque o frame realmente responsável pelo bloqueio nem sempre é a página de nível superior. Obtenha o motivo real no relatório por frame do navegador que está testando, em vez de adivinhar a partir de uma lista geral.

Acertando a sequência de eventos/estado do ciclo de vida

Confundir o que cada evento do ciclo de vida realmente prova com o que apenas sugere é o segundo erro de correção mais comum aqui, depois dos erros de elegibilidade acima:

Evento / estadoSinalO que realmente significaO que fazer
pagehide (event.persisted === true)Intenção de armazenarO navegador está tentando congelar a página para o bfcache — não é uma entrada confirmada no cacheFeche/pause conexões, timers e observers aqui; não presuma que a página será realmente restaurada
freezePausadoA execução do JS está pausada; a página ainda pode ser removida antes de qualquer restauraçãoNenhuma ação além do que já foi feito em pagehide
(nenhum evento) possível remoçãoO navegador pode descartar uma página congelada da memória a qualquer momento — pressão de memória, tempo limite, regra do navegador — e não há evento disparado para issoNão dependa de código de limpeza executado depois; faça-o incondicionalmente em pagehide/freeze
pageshow (event.persisted === true)Restauração confirmadaO único sinal confiável de que uma restauração do bfcache realmente aconteceuAtualize estado sensível/de tempo, reconecte conexões fechadas, conte exatamente uma visualização analítica
resumeRetomadoA execução do JS foi retomada após uma restauração confirmadaReconecte tudo o que foi pausado em freeze

A regra prática: trate pagehide.persisted como intenção, não como prova — a página ainda pode ser removida antes que você veja uma restauração. Apenas pageshow.persisted === true confirma que uma restauração aconteceu. Faça a limpeza incondicionalmente em pagehide/freeze (é barato e seguro até em uma navegação normal) e faça o trabalho específico de restauração somente em pageshow/resume, condicionado a event.persisted, para não atualizar dados nem contar duas vezes uma visualização analítica em um carregamento novo comum.

Como testar e diagnosticar o bfcache

Laboratório / pontual: Chrome DevTools

Abra DevTools → Aplicativo → Serviços em segundo plano → Cache de Voltar/Avançar e clique em Test back/forward cache (tradução) «Testar cache de Voltar/Avançar». O Chrome navega automaticamente para chrome://terms/ e volta, depois informa sucesso ou uma lista específica de motivos de bloqueio. É útil para verificar uma URL de cada vez.

Campo / produção: a API notRestoredReasons

Antes, a única forma de verificar a elegibilidade era aquele teste manual do DevTools, uma URL por vez — não havia como saber por que as navegações de usuários reais estavam bloqueadas. A propriedade notRestoredReasons de PerformanceNavigationTiming (lançada no Chrome 123+) fecha essa lacuna: ela informa os motivos específicos de bloqueio para o frame superior e iframes da mesma origem em dados reais de campo.

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

Alguns pontos precisam ser acertados ao usá-la, diretamente da orientação da própria API do Chrome:

  • Ela funciona apenas no Chrome (123+). Firefox e Safari não expõem uma API de campo equivalente, então você ainda precisa de verificações manuais pontuais nesses navegadores para conhecer sua taxa de restauração neles.
  • Um resultado null é ambíguo, não um sinal verde. Pode significar que a página foi restaurada ou que o navegador simplesmente não coletou um motivo — a documentação do próprio Chrome diz para não tratar null como prova de restauração bem-sucedida.
  • O texto do motivo não é um contrato estável. Não codifique correspondências de strings; agrupe e acompanhe tendências por motivo, pois a formulação exata pode mudar entre versões do Chrome.

Na prática: extraia notRestoredReasons junto das taxas de restauração pageshow.persisted antes e depois de uma correção entrar no ar, compare a tendência em vez de um único snapshot e combine isso com uma verificação manual no DevTools/laboratório no Firefox e no Safari, navegadores que a API não alcança. Esta é a ferramenta para diagnosticar bfcache em escala no RUM/produção, em vez de verificar URLs uma por uma — apenas não a trate como o quadro inteiro.

Bfcache e Core Web Vitals — a relação precisa

Esta é a nuance que a maior parte do conteúdo concorrente mistura, e o ângulo que vale assumir.

Como uma restauração do bfcache é medida. Os navegadores (e, portanto, os dados de campo do CrUX) contam uma navegação restaurada pelo bfcache como um “carregamento de página” extremamente rápido — LCP quase instantâneo e, quando a página está implementada corretamente (nada precisa refazer o layout), efetivamente zero CLS adicional, porque não há nova renderização. Na comparação real do DebugBear, uma página restaurada pelo bfcache atingiu LCP em cerca de 100 ms, contra ~427 ms em um carregamento sem cache. É exatamente por isso que o bfcache aparece como alavanca para CLS e LCP no meu próprio checklist de CLS da Ahrefs, onde coloco de forma simples: “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.” (tradução) «Garanta que suas páginas sejam elegíveis para o bfcache. O cache de Voltar/Avançar mantém páginas no cache do navegador e carrega instantaneamente uma página já visitada, sem causar mudanças de layout.»

Há duas ressalvas de escopo que merecem precisão, pois é aqui que o conteúdo concorrente costuma exagerar. Primeiro, isso afeta apenas as navegações que o CrUX classifica como voltar/avançar (sua dimensão navigation-type) — não diz nada sobre primeiras visitas ou recarregamentos, que são a maioria do tráfego na maior parte dos sites. Segundo, uma restauração melhorar a experiência medida dos usuários que a obtêm não é uma garantia: quem for removido do bfcache (veja a tabela do ciclo de vida acima) ainda terá um carregamento normal e sem essa melhoria, portanto o trabalho de elegibilidade move sua taxa de restauração entre as navegações de Voltar/Avançar, não uma parcela fixa do tráfego total — e não garante sua avaliação agregada de Core Web Vitals em campo, seus rankings ou sua taxa de conversão. É uma alavanca real, mensurável e de escopo específico, não uma correção geral de desempenho ou SEO.

O bfcache é um fator de ranqueamento? Não. Esta é a afirmação defensável e diferenciada. A própria documentação de ranqueamento dos Core Web Vitals do Google não menciona bfcache. A cadeia honesta de influência é: elegibilidade do bfcache → melhores números de CWV em campo (principalmente LCP/CLS) nas navegações de voltar/avançar → Core Web Vitals é um entre vários sinais de “experiência na página” que o Google diz estar alinhado ao que seus sistemas de ranqueamento já valorizam. Isso é uma afirmação materialmente mais fraca e precisa do que “o bfcache aumenta rankings” — e é a afirmação que o conteúdo concorrente deveria fazer, mas normalmente não formula com cuidado. O bfcache também é, corretamente, um recurso do mecanismo de renderização, não do crawler — não tem relação com a forma como Googlebot ou Bingbot rastreiam suas páginas; por isso, não existe uma “posição do Bing sobre bfcache para SEO” como existe para robots.txt ou sitemaps.

SPAs e navegações suaves. O bfcache opera em navegações e eventos reais do histórico do navegador. Uma mudança de rota “suave” no lado do cliente de um aplicativo de página única (uma troca de visualização conduzida por JS que não dispara uma navegação real do navegador) não é um evento de bfcache e não recebe o mesmo tratamento. Tentativas de algumas ferramentas de RUM de atribuir Core Web Vitals a navegações suaves podem criar divergências de medição entre CrUX e RUM — um ponto que vale destacar ao auditar um site baseado em framework JS.

Quão comuns são os bloqueadores de bfcache no mundo real?

O Web Almanac do HTTP Archive acompanha isso, e é uma área viva e mutável — não uma notícia antiga já resolvida. Na edição de 2022, pelo menos ~22% das páginas mobile eram inelegíveis para bfcache apenas pelos critérios de unload e no-store. Desde então, o uso de handlers de unload vem caindo entre níveis de site e dispositivos — mas o uso de Cache-Control: no-store subiu (o capítulo de 2025 o coloca em cerca de 23% dos sites, contra ~21% em 2024, parcialmente atribuído ao aumento de experiências autenticadas/personalizadas e a requisitos de conformidade mais rigorosos).

A descoberta contraintuitiva que vale citar: sites maiores e com mais tráfego têm probabilidade desproporcionalmente maior de bloquear o próprio bfcache. Entre os mil sites principais, cerca de 28% das páginas desktop e 20% das mobile ainda usam handlers de unload, contra apenas ~11% desktop / ~10% mobile em todos os sites — frequentemente porque sites maiores carregam mais código legado de analytics dependente de unload. Os sites com mais tráfego de voltar/avançar a perder são muitas vezes os que ainda se atrapalham sozinhos.

Onde isso se encaixa

O bfcache é uma entre várias alavancas de desempenho neste cluster. Seu retorno aparece nos dados de campo dos Core Web Vitals — especificamente em Cumulative Layout Shift e Largest Contentful Paint, já que uma página restaurada é exibida instantaneamente sem refazer o layout. Ele é diferente de cache, que armazena arquivos em vez de um snapshot da página viva, embora os dois compartilhem o cabeçalho Cache-Control como ponto de contato. Não há relação direta com Interaction to Next Paint, então não vou forçar uma.

Add an expert note

Pin an expert quote

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