Glossário

Por que beforeunload vs pagehide decide se o analytics sobrevive

Taras Shynkarenko
Taras Shynkarenko
•Atualizado: •7 min de leitura
Por que beforeunload vs pagehide decide se o analytics sobrevivePor que beforeunload vs pagehide decide se o analytics sobrevive

TL;DR, Resposta rápida

7 min de leitura

A escolha entre beforeunload vs pagehide importa porque beforeunload não dispara de forma confiável no celular e, no Firefox, desqualifica a página do back-forward cache. O pagehide dispara nas mesmas navegações sem esse custo de bfcache, e o MDN recomenda visibilitychange primeiro, pagehide como alternativa, junto com sendBeacon para enviar o analytics antes de a página desaparecer.

Por que beforeunload vs pagehide importa para enviar analytics?

Escolher certo entre beforeunload vs pagehide decide se um evento de analytics realmente chega ao servidor antes de o usuário sair da página. O MDN documenta que o beforeunload não dispara de forma confiável, principalmente no celular: um usuário que troca para outro app e depois fecha o navegador pelo gerenciador de apps nunca chega a disparar o evento. Use pagehide ou visibilitychange para enviar dados em vez de beforeunload, e reserve o beforeunload para a única tarefa que ele ainda cumpre bem, avisar o usuário sobre alterações não salvas. Errar nisso é um dos motivos mais silenciosos pelos quais uma configuração de monitoramento de usuários reais subconta as saídas.

O que o evento beforeunload realmente faz?

O evento beforeunload dispara pouco antes de a página ser descarregada e pode mostrar uma caixa de diálogo de confirmação nativa do navegador para avisar o usuário sobre alterações não salvas. A própria orientação do MDN é adicionar o listener só quando houver alterações não salvas para proteger, e removê-lo assim que essas alterações forem salvas, em vez de deixá-lo anexado durante toda a vida da página. Esse caso de uso restrito também é o único para o qual ele ainda serve, já que sua confiabilidade como sinal geral de saída não existe.

Uma mão passando por aplicativos abertos no celular, o momento do alternador de apps que pula eventos de saída no celular.

Por que o beforeunload é pouco confiável no celular?

O beforeunload é pouco confiável no celular porque um navegador fechado pelo seletor de apps, ou um app colocado em segundo plano e nunca reaberto, pula o evento por completo, o que o MDN aponta diretamente no cenário de trocar de app e depois fechar. Uma aba de desktop fechada pelos controles da janela dispara o evento; a mesma sequência num celular, colocar o app em segundo plano e fechá-lo pelo gerenciador de apps, pula o evento por completo. Qualquer chamada de analytics que dependa só do disparo do beforeunload perde dados exatamente na plataforma onde as sessões terminam desse jeito.

Mesmo fechamento, resultado diferente
Fechamento de aba no desktop
  • O usuário clica nos controles da janela
  • O beforeunload dispara
Troca de app no celular
  • O usuário coloca o app em segundo plano e depois o fecha pelo gerenciador de apps
  • O beforeunload nunca dispara
O exemplo do MDN sobre a troca de apps mostra que o mesmo caminho de saída pula o evento por completo no celular.

Como o beforeunload afeta o back-forward cache?

O efeito do beforeunload sobre o back-forward cache muda de navegador para navegador: o Firefox não coloca uma página no bfcache se ela tiver um listener de beforeunload anexado, enquanto o guia de bfcache do web.dev aponta que o beforeunload não desqualifica mais uma página do bfcache em outros navegadores modernos, embora antes desqualificasse. O web.dev ainda chama o evento de "pouco confiável, então evite usá-lo a menos que seja absolutamente necessário", e recomenda adicionar o listener de forma condicional, só enquanto existirem alterações não salvas, em vez de em todo carregamento de página. Uma página que pula o bfcache recarrega do zero numa navegação para trás, em vez de ser restaurada instantaneamente da memória.

Uma pessoa fechando um notebook, o momento em que uma página é ocultada antes de o navegador mostrar outra.

O que o evento pagehide faz de diferente?

O evento pagehide dispara quando o navegador oculta a página atual enquanto apresenta outra página do histórico de sessão, como um clique no botão voltar, e diferente de beforeunload e unload, um listener de pagehide não torna a página inelegível para o bfcache. O MDN recomenda visibilitychange primeiro como o sinal mais confiável, com pagehide como alternativa para navegadores onde visibilitychange não está disponível. Anexe a lógica de envio ao pagehide quando a página precisar de um listener seguro para o bfcache que ainda assim dispare nos mesmos momentos de navegação que o beforeunload deveria capturar, o que também é o momento em que um relógio de timeout de sessão continuaria correndo contra uma página que ninguém está olhando.

EventoDispara de forma confiável no celular?Bloqueia o bfcache?Melhor uso
unloadNão, o MDN chama de "extremamente pouco confiável" no celularSim, no Chrome e Firefox de desktopEvitar; só código legado
beforeunloadNão, segundo o exemplo de troca de app do MDNNão nos navegadores modernos, segundo o web.devSó para avisar sobre alterações não salvas
pagehideSinal alternativo segundo o MDNNãoEnviar analytics quando visibilitychange não está disponível
visibilitychangeSinal principal recomendado pelo MDNNãoEnviar analytics ao ocultar a aba, primeira escolha

Onde o sendBeacon se encaixa ao lado do pagehide?

O sendBeacon se encaixa ao lado do pagehide como mecanismo de entrega, já que ele enfileira uma requisição POST assíncrona que o navegador continua tentando enviar mesmo enquanto a página desaparece, sem atrasar a navegação que o usuário já está fazendo. O MDN recomenda combiná-lo com o evento visibilitychange como gatilho principal e pagehide como alternativa, em vez de dispará-lo a partir de unload ou beforeunload. Uma única chamada de sendBeacon é limitada a cerca de 64 KiB; uma carga maior que isso precisa de fetch() com a opção keepalive no lugar.

Como um script de analytics deve combinar esses eventos?

Um script de analytics deve escutar visibilitychange e verificar document.visibilityState === "hidden" como gatilho principal de envio, adicionar pagehide como alternativa para navegadores ou situações em que visibilitychange não dispara, e chamar sendBeacon nos dois handlers para enviar a carga sem bloquear a navegação. O script leve da Flowsery pesa menos de 10 KB justamente para que essa lógica de listeners adicione peso desprezível a uma página que já está tentando sair. Pular direto para o beforeunload nessa tarefa é o atalho que mais custa dados no celular, e é o mesmo atalho que desinfla silenciosamente uma contagem de bounce rate vs exit rate quando o último evento de uma página nunca chega ao servidor.

Enviando analytics antes de a página desaparecer
1
Escute visibilitychange. Verifique document.visibilityState === "hidden" como sinal principal.
2
Adicione pagehide como alternativa. Cobre os casos em que visibilitychange não dispara.
3
Envie com sendBeacon. Enfileira um POST assíncrono que não atrasa a navegação.
4
Deixe beforeunload só para alterações não salvas. Adicione condicionalmente, remova depois de salvar.
A ordem que o MDN e o web.dev recomendam para um envio de saída confiável e seguro para o bfcache.

Perguntas frequentes

O beforeunload ainda é útil para alguma coisa?

O beforeunload ainda é útil para avisar o usuário sobre alterações não salvas por meio de uma caixa de diálogo de confirmação nativa do navegador. A própria recomendação do MDN é anexar o listener só enquanto existirem alterações não salvas e removê-lo assim que forem salvas, em vez de usá-lo como sinal geral de saída de página.

Por que o pagehide não bloqueia o back-forward cache como o beforeunload bloqueava antes?

O pagehide não bloqueia o bfcache porque foi projetado como parte da Page Lifecycle API especificamente para sinalizar uma transição de página sem os efeitos colaterais que unload e beforeunload carregam. O MDN afirma claramente que, diferente de unload e beforeunload, um listener de pagehide não torna a página inelegível para o bfcache.

O visibilitychange deveria substituir o pagehide por completo?

O visibilitychange deveria ser o sinal principal, com o pagehide mantido como alternativa, segundo a própria orientação do MDN. Alguns navegadores ou contextos não disparam visibilitychange em todo cenário de saída, então o pagehide cobre os casos que o visibilitychange perde em vez de substituí-lo por completo.

O que acontece se uma chamada de analytics usar fetch em vez de sendBeacon na saída da página?

Uma chamada fetch comum iniciada durante a saída da página pode ser cancelada antes de o navegador terminar de enviá-la, já que a página já está sendo descarregada. O sendBeacon existe justamente para evitar isso: o navegador aceita a requisição e continua tentando entregá-la independentemente de a página já ter desaparecido, até seu limite de cerca de 64 KiB.

O back-forward cache afeta o analytics de alguma forma?

O back-forward cache restaura uma página da memória numa navegação para trás ou para frente em vez de recarregá-la, o que significa que o JavaScript da página não roda de novo e nenhuma lógica de pageview que dependa de um carregamento novo dispara de novo. Um evento pageshow com event.persisted === true é o sinal de que uma restauração aconteceu, algo que a lógica de analytics precisa verificar separadamente de um primeiro carregamento.

Por que o Firefox trata o beforeunload de forma diferente dos outros navegadores para o bfcache?

O Firefox desqualifica uma página do bfcache se ela tiver um listener de beforeunload anexado, uma postura mais rígida do que a de navegadores que pararam de desqualificar páginas com beforeunload do bfcache depois de terem feito isso antes. A escolha mais segura entre navegadores continua sendo adicionar um listener de beforeunload só quando existirem alterações não salvas, já que isso mantém o listener fora da página durante as navegações em que a elegibilidade para o bfcache mais importa.

Flowsery
Flowsery

Comece seu teste grátis de 14 dias

Painel em tempo real

Rastreamento de metas

Rastreamento sem cookies

O que acontece se um payload de analytics ultrapassar o limite de 64 KiB do sendBeacon?

Uma chamada sendBeacon, limitada a cerca de 64 KiB, rejeita de vez um payload maior, que nunca chega ao servidor. Trocar para fetch com a opção keepalive dá conta de payloads acima desse limite e ainda sobrevive a uma página que já está descarregando.

O evento unload é um fallback mais seguro que o beforeunload?

Unload é pior, não mais seguro. O MDN o chama de extremamente pouco confiável no celular, e ele ainda bloqueia o back-forward cache no Chrome e no Firefox no desktop, exatamente o custo que o pagehide existe para evitar. Vale tratá-lo como código legado a evitar, não como um fallback a usar.

Adicionar listeners de pagehide e visibilitychange deixa a página mais pesada?

O Flowsery entrega seu script com menos de 10 KB justamente para que essa lógica de listeners agregue peso insignificante a uma página que já está tentando sair. O custo real está no tamanho do payload do sendBeacon, não nos listeners em si.

Como o envio no pagehide afeta o rastreamento de timeout de sessão?

O pagehide dispara no momento exato em que uma página fica escondida atrás de outra no histórico de sessão, que é também o momento em que um relógio de timeout de sessão continuaria rodando contra uma página que ninguém mais está vendo. Enviar os dados nesse instante encerra a sessão na hora certa, em vez de acumular tempo ocioso contra uma aba que o usuário já abandonou.

Este artigo foi útil?

Diga-nos o que pensa!

Veja-nos mais no Google

Um clique marca a Flowsery como fonte preferida e nossos artigos passam a aparecer mais acima nas suas Principais notícias, no modo IA e nas visões gerais com IA.

Antes de ir...

Flowsery

Flowsery

Analytics orientado para receitas para o seu site

Rastreie cada visitante, fonte e conversão em tempo real. Simples, poderoso e sem cookies.

Painel em tempo real

Rastreamento de metas

Rastreamento sem cookies

Termos relacionados do glossário

Lendo página de entrada vs landing page no GA4 e no AdobeLendo página de entrada vs landing page no GA4 e no Adobe
Glossário

Lendo página de entrada vs landing page no GA4 e no Adobe

A divisão entre página de entrada vs landing page importa porque o GA4 entrega só Landing page e o Adobe só Entry page, calculadas de campos diferentes.

•9 min de leitura
Por que o significado de visitantes únicos muda de ferramenta para ferramentaPor que o significado de visitantes únicos muda de ferramenta para ferramenta
Glossário

Por que o significado de visitantes únicos muda de ferramenta para ferramenta

O significado de visitantes únicos depende da ferramenta: o GA4 estima, o Matomo não calcula em períodos longos e a Adobe deduplica no relatório inteiro.

•9 min de leitura
Por que sendBeacon vs fetch keepalive é uma decisão de 64 KiBPor que sendBeacon vs fetch keepalive é uma decisão de 64 KiB
Glossário

Por que sendBeacon vs fetch keepalive é uma decisão de 64 KiB

Ao comparar sendBeacon vs fetch keepalive: os dois dividem um orçamento de 64 KiB, mas só o sendBeacon fixa o Content-Type e esconde a resposta do servidor.

•8 min de leitura
O que estes números revelam sobre a taxa de rejeição média por setorO que estes números revelam sobre a taxa de rejeição média por setor
Glossário

O que estes números revelam sobre a taxa de rejeição média por setor

Nove setores rastreados mostram uma taxa de rejeição média por setor documentada, entre 35.76% e 48.38%, segundo dados da Databox de setembro de 2024.

•7 min de leitura
Como sites B2B e B2C se comparam nos benchmarks de duração média de sessãoComo sites B2B e B2C se comparam nos benchmarks de duração média de sessão
Glossário

Como sites B2B e B2C se comparam nos benchmarks de duração média de sessão

A Databox coloca, com dados próprios, os benchmarks de duração média de sessão em 77.61 segundos no B2B e 92.33 segundos no B2C, por setor e dispositivo.

•8 min de leitura
O que a análise de experiência digital cobre e o web analytics perdeO que a análise de experiência digital cobre e o web analytics perde
Glossário

O que a análise de experiência digital cobre e o web analytics perde

Em vez de contar eventos, a análise de experiência digital reconstrói a visita, usando session replay, heatmaps, detecção de atrito e análise de jornada.

•8 min de leitura

Artigos relacionados