Reduzir a navegação atrasada
É comum que uma página ou um app tenha análises ou outros dados não enviados no momento em que um usuário fecha. Para evitar a perda de dados, alguns sites usam uma chamada síncrona
para XMLHttpRequest()
e manter a página ou o app abertos até que os dados sejam transmitidos para
o servidor. Além de haver maneiras melhores de salvar dados, essa técnica cria
uma experiência ruim para o usuário, atrasando o fechamento da página por até vários segundos.
Essa prática precisa mudar, e os navegadores estão reagindo. A especificação XMLHttpRequest()
já está programada para descontinuação e
remoção. O Chrome 80 dá o primeiro
passo ao proibir chamadas síncronas em vários manipuladores de eventos,
especificamente beforeunload
, unload
, pagehide
e visibilitychange
, quando
são acionados na dispensa. O WebKit também fez uma confirmação que implementa
a mesma mudança de comportamento.
Neste artigo, vamos descrever brevemente as opções para quem precisa de tempo para atualizar
os sites e resumir as alternativas para XMLHttpRequest()
.
Desativações temporárias
O Chrome não quer simplesmente desativar o XMLHttpRequest()
. Por isso, algumas
opções temporárias de desativação estão disponíveis. Para sites na Internet, um teste de
origem
está disponível.
Com isso, você adiciona um token específico da origem aos cabeçalhos da página que ativa
chamadas XMLHttpRequest()
síncronas. Essa opção vai ser desativada pouco antes do lançamento do Chrome 89, em algum momento de março de 2021. Os clientes do Chrome Enterprise também podem
usar a flag de política AllowSyncXHRInPageDismissal
, que termina no mesmo período.
Alternativas
Independentemente de como você envia dados de volta ao servidor, é melhor evitar esperar
até a página ser descarregada para enviar todos os dados de uma só vez. Além de criar uma experiência
ruim para o usuário, o unload não é confiável em navegadores modernos e pode causar perda de dados se
algo der errado. Especificamente, os eventos de descarregamento geralmente não são acionados em navegadores
para dispositivos móveis
porque há muitas maneiras de
fechar uma
aba ou um navegador em sistemas operacionais para dispositivos móveis sem que o evento unload
seja acionado.
Com XMLHttpRequest()
, usar payloads pequenos era uma opção. Agora é um
requisito. Ambas as alternativas têm um limite de upload de 64 KB por
contexto, conforme exigido pela especificação.
Buscar indicador de atividade
A API Fetch
oferece um meio robusto de lidar com interações do servidor e uma interface
consistente para uso em diferentes
APIs de plataforma. Entre as opções, está keepalive
, que garante que uma solicitação
continue, independentemente de a página que a fez permanecer aberta ou não:
window.addEventListener('unload', {
fetch('/siteAnalytics', {
method: 'POST',
body: getStatistics(),
keepalive: true
});
}
O método fetch()
tem a vantagem de ter mais controle sobre o que é enviado para
o servidor. O que não mostro no exemplo é que fetch()
também retorna uma
promessa que é resolvida com um objeto Response
. Como estou tentando sair
do caminho da transferência da página, decidi não fazer nada com ela.
SendBeacon()
O SendBeacon()
usa a API Fetch em segundo plano, por isso tem a mesma
limitação de payload de 64 KB e também garante que uma solicitação continue
após o descarregamento de uma página. A principal vantagem é a simplicidade. Ele permite
enviar seus dados com uma única linha de código:
window.addEventListener('unload', {
navigator.sendBeacon('/siteAnalytics', getStatistics());
}
Conclusão
Com o aumento da disponibilidade de
fetch()
em vários navegadores, esperamos que o XMLHttpRequest()
seja removido
da plataforma da Web em algum momento. Os fornecedores de navegadores concordam que ele precisa ser removido, mas isso
vai levar tempo. A descontinuação de um dos piores casos de uso é uma primeira etapa que melhora
a experiência do usuário para todos.
Foto de Matthew Hamilton no Unsplash