Uma pessoa abre a página de preços, visita um caso de uso e toca em voltar. Se o navegador preservou a página anterior no back-forward cache, ou bfcache, a volta pode ser quase instantânea. O DOM, o heap JavaScript e a posição da rolagem retornam sem outra carga completa.

Esse cache não é o cache HTTP. Ele guarda a página inteira em memória por algum tempo. O navegador decide se a página pode entrar, quanto tempo ela fica e quando precisa descartá-la.

O trabalho do site é não bloquear esse mecanismo por engano e continuar correto quando uma página congelada volta à tela.

Comece por uma navegação real

Teste o caminho que alguém faria:

  1. abra a landing page;
  2. role até uma seção intermediária;
  3. abra uma rota interna na mesma aba;
  4. use o botão voltar do navegador;
  5. confirme posição, menu, formulário e conteúdo;
  6. avance e volte mais uma vez.

Não substitua esse roteiro por um reload. Atualizar a página inicia outra navegação e não prova que o bfcache funcionou.

A documentação do web.dev sobre bfcache explica que o navegador pausa a execução da página quando a preserva e retoma as tarefas quando a restaura. Todos os principais navegadores mantêm alguma implementação, mas os critérios não são idênticos.

Distinga bfcache de outros caches

O nome confunde porque há várias camadas no mesmo fluxo.

Camada O que preserva O que acontece ao voltar
cache HTTP respostas de HTML, CSS, JavaScript etc. a página ainda precisa ser reconstruída
Cache Storage respostas controladas pelo site um service worker pode responder por elas
bfcache estado completo da página em memória a página congelada volta à tela
cache da CDN respostas perto do visitante ainda ocorre uma requisição ao edge

Um Cache-Control bem configurado não garante bfcache. Da mesma forma, uma restauração pelo bfcache não revalida o HTML antes de mostrar a página.

O guia de Cache-Control cobre o cache HTTP. Para versões antigas presas no navegador, use o artigo sobre assets antigos depois da republicação.

Rode o teste do DevTools

O Chrome tem um diagnóstico específico:

  1. abra a URL publicada;
  2. abra DevTools;
  3. entre em Application;
  4. escolha Back-forward Cache;
  5. clique em Run Test;
  6. leia o resultado da restauração;
  7. expanda os motivos marcados como acionáveis.

O teste navega para fora e volta. Quando falha, o painel informa os motivos que conseguiu atribuir à página, a um frame ou ao navegador.

Guarde o resultado com URL e Version:

URL:
Version:
navegador e versão:
restaurada pelo bfcache: sim ou não
motivos acionáveis:
frames envolvidos:
estado incorreto depois da volta:

Um resultado positivo no Chrome não substitui Safari e Firefox. Ele oferece uma linha de base reproduzível e localiza bloqueios comuns.

Remova listeners de unload

O evento unload é incompatível com a ideia de congelar uma página e retomá-la depois. No desktop, Chrome e Firefox podem tornar a página inelegível quando encontram esse listener. Em outros cenários, o navegador pode simplesmente não dispará-lo.

Procure no código próprio e em terceiros:

addEventListener("unload"
onunload

Se o objetivo é encerrar uma tarefa ao sair, use pagehide e escreva o fluxo para aceitar que a página pode voltar.

window.addEventListener("pagehide", () => {
stopLiveUpdates();
});
window.addEventListener("pageshow", () => {
startLiveUpdates();
});

As funções precisam ser idempotentes. Uma restauração não pode abrir dois timers, dois observers ou duas conexões.

beforeunload continua útil para avisar sobre alterações não salvas, mas não deve ficar registrado o tempo todo. Adicione o listener somente enquanto houver trabalho que a pessoa realmente perderia e remova-o depois de salvar.

Feche recursos que não podem ficar pausados

Uma landing page simples talvez não abra conexões persistentes. Widgets, áreas autenticadas e formulários avançados podem abrir.

Revise:

  • conexões IndexedDB mantidas abertas;
  • WebSockets e WebRTC;
  • requests ainda em andamento;
  • Web Locks;
  • observers ligados a recursos externos;
  • timers que reiniciam sem controle;
  • SDKs de chat e suporte.

O comportamento varia entre navegadores e versões. A orientação segura é liberar o recurso em pagehide ou freeze e reabrir em pageshow ou resume quando o produto precisar dele.

Não feche uma conexão só para passar no teste. Primeiro confirme quem a criou, como reconectar e o que acontece com mensagens pendentes.

Observe a restauração sem duplicar inicialização

pageshow dispara na carga inicial e na restauração. A propriedade persisted distingue os casos.

window.addEventListener("pageshow", (event) => {
if (!event.persisted) return;
refreshVolatileState();
});

Use essa condição para tarefas específicas da volta, como conferir sessão, preço ou disponibilidade. Não repita toda a inicialização do load dentro dela.

Para observar a saída, pagehide também tem persisted. Um valor verdadeiro indica que o navegador pretende preservar a página, mas não garante que ela permanecerá no cache até a próxima navegação.

Atualize apenas o estado que pode envelhecer

Uma restauração mostra o snapshot guardado. Em uma landing page editorial, isso costuma ser correto. Em uma etapa de compra ou área autenticada, alguns dados podem ter mudado.

Liste o estado volátil:

Estado Ação depois da restauração
sessão autenticada validar antes de exibir dado privado
preço ou disponibilidade buscar a versão atual
formulário não enviado preservar ou limpar conforme o contrato
banner temporário recalcular validade
conteúdo editorial manter se não exige atualização imediata

Não force location.reload() em toda volta. Isso elimina o ganho do bfcache. Recarregue somente quando uma condição de segurança ou consistência exigir a página completa.

Não use no-store como correção genérica

Cache-Control: no-store existe para respostas que não devem ser armazenadas. Ele não é uma forma neutra de pedir conteúdo atualizado e pode reduzir a elegibilidade ao bfcache em alguns navegadores.

Se a página é pública e só precisa revalidar no cache HTTP, avalie no-cache ou max-age=0. Depois trate dados realmente voláteis no pageshow.

Headers dependem do contrato da hospedagem. Confirme a resposta servida na URL e não prometa uma diretiva que o projeto não controla.

Conte a volta sem inflar analytics

Uma restauração pelo bfcache não dispara outra carga completa. Uma biblioteca de analytics pode ignorá-la ou contar eventos duplicados se a inicialização rodar de novo.

Defina antes o que significa uma visualização no produto. Se uma volta deve contar como nova exibição, envie um evento no pageshow quando persisted for verdadeiro. Se não deve, registre apenas o tipo de navegação para diagnóstico.

Não envie dois pageviews por restauração. Verifique a configuração padrão do fornecedor antes de adicionar um listener.

O guia de Core Web Vitals reais mostra como separar tipos de navegação sem misturar visitas restauradas com cargas completas.

Teste o que fica vivo

Depois de remover o bloqueio, repita o roteiro e confira:

  • posição da rolagem;
  • foco e elemento ativo;
  • menu e modal;
  • valores do formulário;
  • timers e carrosséis;
  • conexões reabertas uma única vez;
  • sessão e conteúdo volátil;
  • eventos de analytics;
  • navegação por teclado;
  • botão avançar depois de voltar.

O bfcache pode revelar bugs que um reload escondia. Um componente que dependia de load para se corrigir precisa de um ciclo de vida compatível com restauração.

Publique e repita na URL final

Teste a build local para corrigir rápido. Depois repita na publicação porque headers, scripts externos e domínio próprio podem mudar a elegibilidade.

No Site no Ar:

  1. consulte o Site e a Version atuais;
  2. altere os arquivos em public/;
  3. publique com deploy;
  4. acompanhe deploy_status até o fim;
  5. execute o teste na URL padrão;
  6. repita no domínio próprio, se houver;
  7. registre a Version e os motivos restantes.

A documentação de Publicação explica como a Version chega à URL. O fluxo de republicação preserva o mesmo Site durante a correção.

Prompt para revisar bfcache

Revise o bfcache desta landing page sem publicar ainda.
URL e Version: [URL e identificador]
Rota de saída e retorno: [caminho]
Estado que deve ser preservado: [lista]
1. Rode o teste Back-forward Cache do Chrome DevTools.
2. Liste motivos acionáveis e o frame responsável.
3. Procure unload, beforeunload permanente e conexões abertas.
4. Troque a menor parte necessária por pagehide e pageshow.
5. Garanta que reconexão, timers e observers sejam idempotentes.
6. Teste rolagem, foco, formulário, sessão e analytics ao voltar.
7. Repita em Chrome, Firefox e Safari quando disponíveis.
8. Só proponha a publicação com a evidência e as limitações registradas.

bfcache é uma otimização do navegador, não uma biblioteca para instalar. O ganho aparece quando a página aceita ser pausada, volta com estado correto e deixa o navegador decidir quando pode preservá-la.