API Page Lifecycle

Compatibilidade com navegadores

  • Chrome: 68.
  • Edge: 79.
  • Firefox: incompatível.
  • Safari: incompatível.

Atualmente, os navegadores modernos suspenderão páginas ou as descartarão totalmente quando os recursos do sistema estão restritos. No futuro, os navegadores vão querer fazer isso de forma proativa, para consumir menos energia e memória. A API Page Lifecycle oferece hooks de ciclo de vida para que suas páginas possam processar com segurança essas intervenções do navegador sem afetar a experiência do usuário. Confira a API para saber se você precisa implementar esses recursos no seu app.

Contexto

O ciclo de vida do aplicativo é uma forma essencial de gerenciar recursos para os sistemas operacionais modernos. No Android, no iOS e em versões recentes do Windows, os apps podem ser iniciados e parados a qualquer momento pelo SO. Isso permite que essas plataformas simplifiquem e realoquem os recursos onde melhor beneficiam o usuário.

Historicamente, na Web não existe esse ciclo de vida, e os apps podem ser mantidos ativos indefinidamente. Com um grande número de páginas da Web em execução, recursos críticos do sistema, como memória, CPU, bateria e rede, podem ser consumidos em excesso, provocando uma experiência ruim para o usuário.

Embora a plataforma da Web já tenha eventos relacionados aos estados do ciclo de vida, como load, unload e visibilitychange, esses eventos só permitem que os desenvolvedores respondam a mudanças de estado do ciclo de vida iniciadas pelo usuário. Para que a Web funcione de maneira confiável em dispositivos de baixa potência (e seja mais consciente dos recursos em geral em todas as plataformas), os navegadores precisam de uma maneira de recuperar e realocar proativamente os recursos do sistema.

Na verdade, os navegadores de hoje já tomam medidas ativas para economizar recursos em páginas em guias em segundo plano, e muitos navegadores (especialmente o Chrome) gostariam de fazer muito mais para reduzir o impacto geral dos recursos.

O problema é que os desenvolvedores não têm como se preparar para esses tipos de intervenções iniciadas pelo sistema ou mesmo saber que elas estão acontecendo. Isso significa que os navegadores precisam ser conservadores ou correm o risco de quebrar as páginas da Web.

A API Page Lifecycle tenta resolver esse problema da seguinte maneira:

  • Introdução e padronização do conceito de estados do ciclo de vida na Web.
  • Definir novos estados iniciados pelo sistema que permitem que os navegadores limitem os recursos que podem ser consumidos por guias ocultas ou inativas.
  • Criação de novas APIs e eventos que permitem que desenvolvedores da Web respondam a transições para e a partir desses novos estados iniciados pelo sistema.

Essa solução oferece a previsibilidade que os desenvolvedores da Web precisam para criar aplicativos resilientes a intervenções do sistema e permite que os navegadores otimizem mais agressivamente os recursos do sistema, beneficiando todos os usuários da Web.

No restante desta postagem, vamos apresentar os novos recursos do ciclo de vida da página e mostrar como eles se relacionam a todos os estados e eventos da plataforma da Web existentes. Ele também fornecerá recomendações e práticas recomendadas para os tipos de trabalho que os desenvolvedores podem (ou não) fazer em cada estado.

Visão geral dos estados e eventos do ciclo de vida da página

Todos os estados do ciclo de vida da página são discretos e mutuamente exclusivos, o que significa que uma página só pode estar em um estado por vez. E a maioria das mudanças no estado do ciclo de vida de uma página geralmente é observável por eventos do DOM. Consulte as recomendações para desenvolvedores de cada estado para ver as exceções.

Talvez a maneira mais fácil de explicar os estados do ciclo de vida da página, bem como os eventos que sinalizam transições entre eles, seja com um diagrama:

Uma representação visual do estado e do fluxo de eventos descritos neste documento.
Estado da API Page Lifecycle e fluxo de eventos.

Estados

A tabela a seguir explica cada estado em detalhes. Ele também lista os possíveis estados que podem ocorrer antes e depois, bem como os eventos que os desenvolvedores podem usar para observar mudanças.

Estado Descrição
Ativa

Uma página está no estado ativo se estiver visível e tiver foco de entrada.

Possíveis estados anteriores:
passivo (pelo evento focus)
congelado (pelo evento resume e depois o pageshow)

Possíveis estados seguintes:
passivo (pelo evento blur)

Passiva

Uma página está no estado passivo se estiver visível e não tiver foco de entrada.

Possíveis estados anteriores:
ativo (pelo evento blur)
oculto (pelo evento visibilitychange)
congelado (pelo evento resume, depois pelo evento pageshow{/22)

Possíveis próximos estados:
ativo (pelo evento focus)
oculto (pelo evento visibilitychange)

Ocultos

Uma página fica no estado oculto quando não está visível (e não foi congelada, descartada ou encerrada).

Possíveis estados anteriores:
passivo (pelo evento visibilitychange)
congelado (pelo evento resume e depois o pageshow)

Possíveis próximos estados:
passivo (pelo evento visibilitychange)
congelado (pelo evento freeze)
descartado (nenhum evento acionado)
encerrado (nenhum evento acionado)

Congelado

No estado congelado, o navegador suspende a execução de tarefas freezáveis nas filas de tarefas da página até que ela seja descongelada. Isso significa que coisas como timers de JavaScript e callbacks de busca não são executados. As tarefas que já estão em execução podem ser concluídas (principalmente o callback freeze), mas podem ser limitadas em relação ao que podem fazer e por quanto tempo podem ser executadas.

Os navegadores congelam páginas como uma forma de preservar o uso da CPU/bateria/dados. Eles também fazem isso para permitir navegações para frente/para trás mais rápidas, evitando a necessidade de uma recarga completa da página.

Possíveis estados anteriores:
oculto (pelo evento freeze)

Possíveis estados seguintes:
ativo (pelo evento resume e depois pelo evento pageshow)
passivo (pelo evento resume e depois pelo evento pageshow)
oculto (pelo evento resume)
descartado (nenhum evento acionado)

Encerrado

A página fica no estado encerrado depois de começar a ser descarregada e limpa da memória pelo navegador. Nenhuma nova tarefa pode ser iniciada nesse estado, e as tarefas em andamento podem ser encerradas se durarem muito.

Possíveis estados anteriores:
oculto (no evento pagehide)

Possíveis estados seguintes:
NENHUMA

Descartado

Uma página fica no estado descartada quando é descarregada pelo navegador para economizar recursos. Nenhuma tarefa, callback de evento ou JavaScript de qualquer tipo pode ser executado nesse estado, porque descartes normalmente ocorrem com restrições de recursos, em que é impossível iniciar novos processos.

No estado descartado, a guia (incluindo o título e o ícone da guia) geralmente fica visível para o usuário, mesmo que a página não esteja mais disponível.

Possíveis estados anteriores:
oculto (nenhum evento disparado)
congelado (nenhum evento acionado)

Possíveis estados seguintes:
NENHUMA

Eventos

Os navegadores distribuem muitos eventos, mas apenas uma pequena parte deles sinaliza uma possível mudança no estado do ciclo de vida da página. A tabela a seguir descreve todos os eventos relacionados ao ciclo de vida e lista os estados para os quais eles podem fazer a transição.

Nome Detalhes
focus

Um elemento DOM recebeu foco.

Observação: um evento focus não necessariamente sinaliza uma mudança de estado. Ele só sinalizará uma mudança de estado se a página não tiver anteriormente o foco de entrada.

Possíveis estados anteriores:
inativo

Estados atuais possíveis:
ativo

blur

Um elemento DOM perdeu o foco.

Observação: um evento blur não necessariamente sinaliza uma mudança de estado. Ele só sinalizará uma mudança de estado se a página não tiver mais o foco de entrada (ou seja, a página não apenas mudou o foco de um elemento para outro).

Possíveis estados anteriores:
ativo

Estados atuais possíveis:
passivo

visibilitychange

O valor de visibilityState do documento foi alterado. Isso pode acontecer quando um usuário navega para uma nova página, alterna de guia, fecha uma guia, minimiza ou fecha o navegador ou alterna entre apps em sistemas operacionais para dispositivos móveis.

Possíveis estados anteriores:
passivo
oculto

Possíveis estados atuais:
passivo
oculto

freeze *

A página foi congelada. Nenhuma tarefa congelada nas filas de tarefas da página será iniciada.

Possíveis estados anteriores:
oculto

Possíveis estados atuais:
congelado

resume *

O navegador retomou uma página congelada.

Possíveis estados anteriores:
congelado

Possíveis estados atuais:
ativo (se seguido pelo evento pageshow)
passivo (se seguido pelo evento pageshow)
oculto

pageshow

Uma entrada de histórico de sessão está sendo acessada.

Pode ser um carregamento de página totalmente novo ou uma página tirada do cache de avanço e retorno. Se a página foi extraída do cache de avanço e retorno, a propriedade persisted do evento será true. Caso contrário, será false.

Possíveis estados anteriores:
congelado (um evento resume também teria sido disparado)

Estados atuais possíveis:
ativo
passivo
oculto

pagehide

Uma entrada do histórico de sessão está sendo percorrida.

Se o usuário estiver navegando para outra página e o navegador puder adicionar a página atual ao cache de ida e volta para ser reutilizada mais tarde, a propriedade persisted do evento será true. Quando true, a página entra no estado congelado. Caso contrário, ela entra no estado encerrado.

Possíveis estados anteriores:
hidden

Possíveis estados atuais:
congelado (event.persisted é verdadeiro, freeze evento a seguir)
encerrado (event.persisted é falso, unload evento a seguir)

beforeunload

A janela, o documento e os recursos dele estão prestes a ser descarregados. O documento continua visível e o evento ainda pode ser cancelado.

Importante: o evento beforeunload só deve ser usado para alertar o usuário sobre mudanças não salvas. Depois que essas mudanças forem salvas, o evento será removido. Ele nunca deve ser adicionado à página de forma incondicional, porque isso pode prejudicar a performance em alguns casos. Consulte a seção sobre APIs legadas para saber mais.

Possíveis estados anteriores:
hidden

Estados atuais possíveis:
encerrado

unload

A página está sendo descarregada.

Aviso: o uso do evento unload nunca é recomendado porque ele não é confiável e pode prejudicar o desempenho em alguns casos. Consulte a seção "APIs legadas" para mais detalhes.

Possíveis estados anteriores:
hidden

Estados atuais possíveis:
encerrado

* Indica um novo evento definido pela API Page Lifecycle

Novos recursos adicionados no Chrome 68

O gráfico anterior mostra dois estados iniciados pelo sistema, e não pelo usuário: congelado e descartado. Como mencionado anteriormente, os navegadores de hoje já congelam e descartam a qualquer momento guias ocultas (a critério deles), mas os desenvolvedores não têm como saber quando isso está acontecendo.

No Chrome 68, os desenvolvedores agora podem observar quando uma guia oculta é congelada e descongelada detectando os eventos freeze e resume em document.

document.addEventListener('freeze', (event) => {
  // The page is now frozen.
});

document.addEventListener('resume', (event) => {
  // The page has been unfrozen.
});

No Chrome 68, o objeto document agora inclui uma propriedade wasDiscarded no Chrome para computador (o suporte para Android está sendo rastreado nesta questão). Para determinar se uma página foi descartada em uma guia escondida, inspecione o valor dessa propriedade no momento do carregamento da página. Observe que páginas descartadas precisam ser recarregadas para serem usadas novamente.

if (document.wasDiscarded) {
  // Page was previously discarded by the browser while in a hidden tab.
}

Para orientações sobre o que é importante fazer nos eventos freeze e resume, além de como lidar e se preparar para o descarte de páginas, consulte as recomendações do desenvolvedor para cada estado.

As próximas seções oferecem uma visão geral de como esses novos recursos se encaixam nos estados e eventos da plataforma da Web.

Como observar os estados do ciclo de vida da página no código

Nos estados ativo, passivo e oculto, é possível executar o código JavaScript que determina o estado atual do ciclo de vida da página com base nas APIs atuais da plataforma da Web.

const getState = () => {
  if (document.visibilityState === 'hidden') {
    return 'hidden';
  }
  if (document.hasFocus()) {
    return 'active';
  }
  return 'passive';
};

Os estados congelado e encerrado, por outro lado, só podem ser detectados no respectivo listener de eventos (freeze e pagehide) à medida que o estado está mudando.

Como observar mudanças de estado

Com base na função getState() definida anteriormente, você pode observar todas as mudanças de estado do ciclo de vida da página com o código abaixo.

// Stores the initial state using the `getState()` function (defined above).
let state = getState();

// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
  const prevState = state;
  if (nextState !== prevState) {
    console.log(`State change: ${prevState} >>> ${nextState}`);
    state = nextState;
  }
};

// Options used for all event listeners.
const opts = {capture: true};

// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
  window.addEventListener(type, () => logStateChange(getState()), opts);
});

// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
  // In the freeze event, the next state is always frozen.
  logStateChange('frozen');
}, opts);

window.addEventListener('pagehide', (event) => {
  // If the event's persisted property is `true` the page is about
  // to enter the back/forward cache, which is also in the frozen state.
  // If the event's persisted property is not `true` the page is
  // about to be unloaded.
  logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);

Esse código faz três coisas:

  • Define o estado inicial usando a função getState().
  • Define uma função que aceita um próximo estado e, se houver uma alteração, registra as mudanças de estado no console.
  • Adiciona capturas de listeners de eventos para todos os eventos de ciclo de vida necessários, que, por sua vez, chamam logStateChange(), transmitindo o próximo estado.

Uma observação sobre o código é que todos os listeners de eventos são adicionados a window e todos eles transmitem {capture: true}. Existem alguns motivos para isso acontecer, entre eles:

  • Nem todos os eventos do ciclo de vida da página têm o mesmo destino. pagehide e pageshow são acionados em window. visibilitychange, freeze e resume são acionados em document, e focus e blur são acionados nos respectivos elementos DOM.
  • A maioria desses eventos não flutua, o que significa que é impossível adicionar detectores de eventos não de captura a um elemento ancestral comum e observar todos eles.
  • A fase de captura é executada antes das fases de destino ou de bolha. Portanto, adicionar listeners garante que eles sejam executados antes que outros códigos possam cancelá-los.

Recomendações para desenvolvedores em cada estado

Como desenvolvedores, é importante entender os estados do ciclo de vida da página e saber como observá-los no código, porque o tipo de trabalho que você deve (ou não) fazer depende muito do estado da página.

Por exemplo, claramente não faz sentido exibir uma notificação transitória para o usuário se a página estiver no estado oculto. Embora esse exemplo seja bastante óbvio, há outras recomendações que não são tão óbvias e valem a pena mencionar.

Estado Recomendações para desenvolvedores
Active

O estado ativo é o momento mais crítico para o usuário e, portanto, o momento mais importante para que sua página seja responsiva à entrada do usuário.

Qualquer trabalho que não seja da interface que possa bloquear a linha de execução principal precisa ter a prioridade reduzida para períodos de inatividade ou transferido para um worker da Web.

Passive

No estado passivo, o usuário não está interagindo com a página, mas ainda pode visualizá-la. Isso significa que as atualizações e animações da interface ainda precisam ser suaves, mas o momento em que essas atualizações ocorrem é menos crítico.

Quando a página muda de ativa para passiva, é um bom momento para persistir o estado do aplicativo não salvo.

Hidden

Quando a página muda de passiva para oculta, é possível que o usuário não interaja com ela novamente até que ela seja recarregada.

A transição para hidden também é geralmente a última mudança de estado que pode ser observada com confiabilidade pelos desenvolvedores. Isso é especialmente verdadeiro em dispositivos móveis, já que os usuários podem fechar guias ou o próprio app do navegador, e os eventos beforeunload, pagehide e unload não são acionados nesses casos.

Isso significa que você precisa tratar o estado oculto como o provável final da sessão do usuário. Em outras palavras, persista qualquer estado de aplicativo não salvo e envie todos os dados de análise não enviados.

Também é preciso parar de fazer atualizações da interface (já que elas não serão vistas pelo usuário) e interromper todas as tarefas que um usuário não quer que sejam executadas em segundo plano.

Frozen

No estado congelado, tarefas que podem ser congeladas nas filas de tarefas são suspensas até que a página seja descongelada, o que pode nunca acontecer (por exemplo, se a página for descartada).

Isso significa que, quando a página muda de oculta para congelada, é essencial interromper os timers ou remover as conexões que, se congeladas, podem afetar outras guias abertas na mesma origem ou a capacidade do navegador de colocar a página no cache de ida/volta.

Em particular, é importante que você:

Você também precisa manter qualquer estado de visualização dinâmico (por exemplo, posição de rolagem em uma visualização de lista infinita) para sessionStorage (ou IndexedDB via commit()) que você quer restaurar se a página for descartada e recarregada mais tarde.

Se a página passar de congelada para oculta, você poderá reabrir as conexões fechadas ou reiniciar as pesquisas interrompidas quando a página foi congelada.

Terminated

Geralmente, não é necessário realizar nenhuma ação quando uma página faz a transição para o estado encerrado.

Como as páginas que estão sendo descarregadas como resultado da ação do usuário sempre passam pelo estado oculto antes de entrar no estado encerrado, o estado oculto é onde a lógica de encerramento de sessão (por exemplo, persistência do estado do aplicativo e geração de relatórios para a análise) precisa ser realizada.

Além disso, conforme mencionado nas recomendações para o estado hidden, é muito importante que os desenvolvedores entendam que a transição para o estado terminated não pode ser detectada de forma confiável em muitos casos (especialmente em dispositivos móveis). Portanto, os desenvolvedores que dependem de eventos de encerramento (por exemplo, beforeunload, pagehide e unload) provavelmente estão perdendo dados.

Discarded

O estado discarded não é observável pelos desenvolvedores no momento em que uma página é descartada. Isso ocorre porque as páginas geralmente são descartadas em restrições de recursos, e descongelar uma página apenas para permitir que o script seja executado em resposta a um evento de descarte simplesmente não é possível na maioria dos casos.

Como resultado, prepare-se para a possibilidade de uma rejeição na mudança de hidden para frozen. Em seguida, você pode reagir à restauração de uma página descartada no momento do carregamento da página verificando document.wasDiscarded.

Mais uma vez, como a confiabilidade e a ordem dos eventos do ciclo de vida não são implementadas de forma consistente em todos os navegadores, a maneira mais fácil de seguir o conselho na tabela é usar PageLifecycle.js.

APIs de ciclo de vida legadas a evitar

Os eventos a seguir devem ser evitados sempre que possível.

O evento de descarregamento

Muitos desenvolvedores tratam o evento unload como um callback garantido e o usam como um sinal de fim de sessão para salvar o estado e enviar dados de análise, mas isso é extremamente não confiável, especialmente em dispositivos móveis. O evento unload não é acionado em muitas situações de remoção típicas, incluindo o fechamento de uma guia do comutador de guias em dispositivos móveis ou o fechamento do app de navegação do comutador de apps.

Por esse motivo, é sempre melhor confiar no evento visibilitychange para determinar quando uma sessão termina e considerar o estado oculto como o último momento confiável para salvar dados do app e do usuário.

Além disso, a mera presença de um manipulador de eventos unload registrado (por onunload ou addEventListener()) pode impedir que os navegadores coloquem páginas no cache de avanço e retorno para carregamentos mais rápidos.

Em todos os navegadores modernos, é recomendável sempre usar o evento pagehide para detectar possíveis descarregamentos de página (também conhecido como estado encerrado) em vez do evento unload. Se você precisar oferecer suporte às versões 10 e anteriores do Internet Explorer, detecte o evento pagehide e use unload apenas se o navegador não oferecer suporte a pagehide:

const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';

window.addEventListener(terminationEvent, (event) => {
  // Note: if the browser is able to cache the page, `event.persisted`
  // is `true`, and the state is frozen rather than terminated.
});

O evento beforeunload

O evento beforeunload tem um problema semelhante ao evento unload, em que, historicamente, a presença de um evento beforeunload pode impedir que as páginas sejam qualificadas para o cache de avanço e retorno. Os navegadores modernos não têm essa restrição. Alguns navegadores, por precaução, não acionam o evento beforeunload ao tentar colocar uma página no cache de avanço e retorno, o que significa que o evento não é confiável como sinal de fim de sessão. Além disso, alguns navegadores (incluindo o Chrome) exigem uma interação do usuário na página antes de permitir que o evento beforeunload seja acionado, afetando ainda mais a confiabilidade.

Uma diferença entre beforeunload e unload é que há usos legítimos de beforeunload. Por exemplo, quando você quer avisar o usuário que ele tem alterações não salvas que serão perdidas se ele continuar descarregando a página.

Como há motivos válidos para usar beforeunload, é recomendável adicionar listeners beforeunload apenas quando um usuário tiver alterações não salvas e removê-las imediatamente depois de serem salvas.

Em outras palavras, não faça isso, já que adiciona um listener beforeunload incondicionalmente:

addEventListener('beforeunload', (event) => {
  // A function that returns `true` if the page has unsaved changes.
  if (pageHasUnsavedChanges()) {
    event.preventDefault();

    // Legacy support for older browsers.
    return (event.returnValue = true);
  }
});

Em vez disso, faça o seguinte (já que ele só adiciona o listener beforeunload quando necessário e o remove quando não é necessário):

const beforeUnloadListener = (event) => {
  event.preventDefault();
  
  // Legacy support for older browsers.
  return (event.returnValue = true);
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  removeEventListener('beforeunload', beforeUnloadListener);
});

Perguntas frequentes

Por que não há um estado "Carregando"?

A API Page Lifecycle define estados discretos e mutuamente exclusivos. Como uma página pode ser carregada no estado ativo, passivo ou oculto e como ela pode mudar de estado ou até ser encerrada antes de terminar o carregamento, um estado de carregamento separado não faz sentido nesse paradigma.

Minha página funciona de forma importante quando está oculta. Como posso impedir que ela seja congelada ou descartada?

Há muitos motivos legítimos para que as páginas da Web não sejam congeladas durante a execução no estado oculto. O exemplo mais óbvio é um app que toca música.

Também há situações em que seria arriscado o Chrome descartar uma página, como se ela contiver um formulário com entrada do usuário não enviada ou se tiver um gerenciador beforeunload que avise quando a página estiver sendo removida.

Por enquanto, o Chrome vai ser conservador ao descartar páginas e só fará isso quando tiver certeza de que não afetará os usuários. Por exemplo, páginas que foram observadas fazendo qualquer uma das seguintes ações enquanto estão no estado oculto não serão descartadas, a menos que estejam sob restrições de recursos extremas:

  • Tocar áudio
  • Como usar o WebRTC
  • Atualizar o título ou o favicon da tabela
  • Como mostrar alertas
  • Como enviar notificações push

Para os recursos de lista atuais usados para determinar se uma guia pode ser congelada ou descartada com segurança, consulte Heurística para congelar e descartar no Chrome.

O que é o cache de avanço e retorno?

O cache de avanço e retorno é um termo usado para descrever uma otimização de navegação implementada por alguns navegadores que acelera o uso dos botões "Voltar" e "Avançar".

Quando um usuário sai de uma página, esses navegadores congelam uma versão dela para que ela possa ser retomada rapidamente caso o usuário volte usando os botões "Voltar" ou "Avançar". Lembre-se de que adicionar um manipulador de eventos unload impede essa otimização.

Para todos os fins e propósitos, esse congelamento é funcionalmente o mesmo que os navegadores de congelamento executam para economizar CPU/bateria. Por esse motivo, ele é considerado parte do estado de ciclo de vida congelado.

Se não for possível executar APIs assíncronas nos estados congelado ou encerrado, como posso salvar dados no IndexedDB?

Em estados congelados e encerrados, tarefas que podem ser congeladas nas filas de tarefas de uma página são suspensas, o que significa que APIs assíncronas e baseadas em callback, como a IndexedDB, não podem ser usadas de forma confiável.

No futuro, vamos adicionar um método commit() aos objetos IDBTransaction, o que vai dar aos desenvolvedores uma maneira de realizar transações somente de gravação que não exigem callbacks. Em outras palavras, se o desenvolvedor estiver apenas gravando dados no IndexedDB e não executando uma transação complexa que consiste em leituras e gravações, o método commit() poderá ser concluído antes que as filas de tarefas sejam interrompidas (assumindo que o banco de dados IndexedDB já esteja aberto).

No entanto, para o código que precisa funcionar hoje, os desenvolvedores têm duas opções:

  • Usar o armazenamento de sessão: o armazenamento de sessão é síncrono e persiste em descartes de página.
  • Use o IndexedDB no service worker: um service worker pode armazenar dados no IndexedDB depois que a página é encerrada ou descartada. No listener de evento freeze ou pagehide, é possível enviar dados para o service worker usando postMessage(), e o service worker pode salvar os dados.

Como testar o app nos estados congelado e descartado

Para testar como o app se comporta nos estados congelados e descartados, acesse chrome://discards para congelar ou descartar qualquer uma das guias abertas.

Interface do Chrome Discards
Abandono da interface do Chrome

Isso permite que você garanta que a página processe corretamente os eventos freeze e resume, bem como a flag document.wasDiscarded, quando as páginas forem recarregadas após um descarte.

Resumo

Os desenvolvedores que querem respeitar os recursos do sistema dos dispositivos dos usuários precisam criar apps pensando nos estados do ciclo de vida da página. É fundamental que as páginas da Web não consumam recursos excessivos do sistema em situações que o usuário não espera.

Quanto mais desenvolvedores começarem a implementar as novas APIs do ciclo de vida da página, mais seguro será para os navegadores congelar e descartar páginas que não estão sendo usadas. Isso significa que os navegadores vão consumir menos memória, CPU, bateria e recursos de rede, o que é uma vitória para os usuários.