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:
- abra a landing page;
- role até uma seção intermediária;
- abra uma rota interna na mesma aba;
- use o botão voltar do navegador;
- confirme posição, menu, formulário e conteúdo;
- 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:
- abra a URL publicada;
- abra DevTools;
- entre em Application;
- escolha Back-forward Cache;
- clique em Run Test;
- leia o resultado da restauração;
- 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ãomotivos 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"onunloadSe 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:
- consulte o Site e a Version atuais;
- altere os arquivos em
public/; - publique com
deploy; - acompanhe
deploy_statusaté o fim; - execute o teste na URL padrão;
- repita no domínio próprio, se houver;
- 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.
