API Page Lifecycle

Compatibilidade com navegadores

  • 68
  • 79
  • x
  • x

Atualmente, os navegadores mais recentes podem suspender ou descartar páginas totalmente quando os recursos do sistema estão limitados. No futuro, os navegadores vão fazer isso proativamente para consumir menos energia e memória. A API Page Lifecycle fornece hooks de ciclo de vida para que suas páginas possam processar essas intervenções do navegador com segurança, sem afetar a experiência do usuário. Analise a API para conferir se é necessário implementar esses recursos no aplicativo.

Contexto

O ciclo de vida do aplicativo é uma forma fundamental dos sistemas operacionais modernos gerenciarem recursos. Nas versões Android, iOS e recentes do Windows, os apps podem ser iniciados e interrompidos a qualquer momento pelo SO. Isso permite que essas plataformas simplifiquem e realoquem recursos da maneira mais benéfica para o usuário.

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

Embora a plataforma da Web tenha há muito tempo eventos relacionados a 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 de recursos em geral em todas as plataformas), os navegadores precisam de uma maneira de recuperar e realocar os recursos do sistema de forma proativa.

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

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

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

  • Apresentação e padronização do conceito de estados do ciclo de vida na Web.
  • Definição de estados novos e 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 os desenvolvedores da Web respondam a transições para esses novos estados iniciados pelo sistema e a partir deles.

Essa solução oferece a previsibilidade que os desenvolvedores da Web precisam para criar aplicativos resistentes a intervenções do sistema. Além disso, ela permite que os navegadores otimizem os recursos do sistema de maneira mais agressiva, beneficiando todos os usuários da Web.

No restante desta postagem, apresentaremos os novos recursos de ciclo de vida da página e exploraremos como eles se relacionam com todos os estados e eventos da plataforma da Web existente. Ele também oferece recomendações e práticas recomendadas para os tipos de trabalho que os desenvolvedores podem (ou não) realizar 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. Além disso, a maioria das mudanças no estado do ciclo de vida de uma página costuma ser observável por meio de eventos DOM. Consulte as recomendações do desenvolvedor para 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 as transições entre eles, seja com um diagrama:

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

Estados

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

Estado Descrição
Ativa

A página fica no estado ativo quando está visível e tem foco de entrada.

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

Próximos estados possíveis:
passivo (por meio do evento blur)

Passivo

Uma página fica no estado passivo quando está visível e não tem foco de entrada.

Possíveis estados anteriores:
ativo (no evento blur)
oculto (no evento visibilitychange)
congelado (no evento resume, depois no /}pageshow

Próximos estados possíveis:
ativo (no evento focus)
oculto (no 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 (por meio do evento visibilitychange)
congelado (no evento resume e depois no evento pageshow)

Próximos estados possíveis:
passivo (por meio do evento visibilitychange)
congelado (no evento freeze)
descartado (nenhum evento acionado)
encerrado (nenhum evento acionado)

Congelado

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

Os navegadores congelam as páginas para preservar o uso de CPU/bateria/dados. Eles também fazem isso para permitir navegações de avanço e retorno mais rápidas, evitando a necessidade de recarregar toda a página.

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

Próximos estados possíveis:
ativo (no evento resume, depois o pageshow evento)
passivo resume, depois o pageshow, o evento pageshow enviado
o evento oculto o evento oculto.

resume

Encerrado

Quando uma página começa a ser descarregada e apagada do navegador, a página passa para o estado encerrado. Nenhuma nova tarefa pode ser iniciada nesse estado, e tarefas em andamento podem ser eliminadas se forem executadas por muito tempo.

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

Próximos estados possíveis:
NENHUM

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, já que o descarte geralmente ocorre sob restrições de recursos, em que a inicialização de novos processos é impossível.

No estado descartado, a própria guia (incluindo o título e o favicon) geralmente fica visível para o usuário, mesmo que a página tenha sido removida.

Estados anteriores possíveis:
oculto (nenhum evento acionado)
congelado (nenhum evento acionado)

Próximos estados possíveis:
NENHUM

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 abaixo descreve todos os eventos que pertencem ao ciclo de vida e lista os estados de e para os quais eles podem fazer a transição.

Nome Detalhes
focus

Um elemento DOM recebeu foco.

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

Possíveis estados anteriores:
passivo

Possíveis estados atuais:
ativo

blur

Um elemento DOM perdeu o foco.

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

Possíveis estados anteriores:
ativo

Possíveis estados atuais:
passivo

visibilitychange

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

Possíveis estados anteriores:
passivo
oculto

Possíveis estados atuais:
passivo
oculto

freeze *

A página acaba de ser congelada. As tarefas congeláveis nas filas de tarefas da página não serão iniciadas.

Possíveis estados anteriores:
oculto

Estados atuais possíveis:
congelado

resume *

O navegador retomou a página congelada.

Possíveis estados anteriores:
congelado

Estados atuais possíveis:
ativo (se seguido pelo evento pageshow)
passivo (se seguido pelo evento pageshow)
oculto

pageshow

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

Ele pode ser um carregamento de página novo ou uma página extraída do cache de avanço e retorno. Se a página tiver sido retirada 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)

Possíveis estados atuais:
ativo
passivo
oculto

pagehide

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

Se o usuário estiver navegando para outra página e o navegador conseguir adicionar a página atual ao cache de avanço e retorno para ser reutilizada depois, a propriedade persisted do evento será true. Quando true, a página entra no estado congelado. Caso contrário, entra no estado encerrado.

Possíveis estados anteriores:
oculto

Estados atuais possíveis:
congelado (event.persisted é verdadeiro, o evento freeze segue)
terminated (event.persisted é falso, unload evento segue)

beforeunload

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

Importante:o evento beforeunload só pode ser usado para alertar o usuário sobre mudanças não salvas. Depois que essas alterações forem salvas, o evento será removido. O botão nunca deve ser adicionado incondicionalmente à página. Isso pode prejudicar o desempenho em alguns casos. Consulte a seção de APIs legadas para saber mais.

Possíveis estados anteriores:
oculto

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 de APIs legadas para mais detalhes.

Possíveis estados anteriores:
oculto

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 que são iniciados pelo sistema, e não pelo usuário: congelado e descartado. Como mencionado anteriormente, os navegadores atuais já congelam e descartam 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 ao Android está sendo acompanhado nesse problema). Para determinar se uma página foi descartada enquanto estava em uma guia oculta, inspecione o valor dessa propriedade no tempo de carregamento da página. Observação: as 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 receber 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 para desenvolvedores de cada estado.

As próximas seções oferecem uma visão geral de como esses novos recursos se encaixam nos estados e eventos atuais 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 um código JavaScript que determina o estado atual do ciclo de vida da página usando APIs de plataforma da Web.

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

Por outro lado, os estados congelado e encerrado só podem ser detectados no respectivo listener de eventos (freeze e pagehide) enquanto o estado está mudando.

Como observar as mudanças de estado

Ao criar 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 a seguir.

// 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 listeners de eventos de captura para todos os eventos de ciclo de vida necessários que, por sua vez, chamam logStateChange(), transmitindo o próximo estado.

Algo a observar sobre o código é que todos os listeners de eventos são adicionados a window e 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 disparados em window, visibilitychange, freeze e resume são disparados em document, e focus e blur são disparados nos respectivos elementos DOM.
  • A maioria desses eventos não aparece, o que significa que é impossível adicionar listeners de eventos que não são de captura a um elemento ancestral comum e observar todos eles.
  • A fase de captura é executada antes das fases de destino ou da bolha. Portanto, adicionar listeners nela ajuda a garantir que eles sejam executados antes que outro código possa cancelá-los.

Recomendações dos desenvolvedores para 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ê precisa (ou não) fazer depende muito do estado da sua página.

Por exemplo, claramente não faz sentido mostrar uma notificação temporária ao usuário se a página estiver oculta. Embora esse exemplo seja bastante óbvio, há outras recomendações que não são tão óbvias que vale a pena enumerar.

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 a página responda à entrada do usuário.

Qualquer trabalho que não seja da interface e que bloqueie a linha de execução principal não seja priorizado para períodos de inatividade ou descarregado para um worker da Web.

Passive

No estado passivo, o usuário não está interagindo com a página, mas ainda consegue vê-la. Isso significa que as atualizações e animações da interface ainda precisam ser suaves, mas o momento de ocorrência delas é menos crítico.

Quando a página muda de ativa para passiva, este é um bom momento para manter 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 oculta também costuma ser a última mudança de estado que pode ser observada com segurança pelos desenvolvedores. Isso é especialmente válido em dispositivos móveis, já que os usuários podem fechar guias ou o próprio app de navegação, 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 final provável da sessão do usuário. Em outras palavras, mantenha o estado do aplicativo não salvo e envie os dados de análise não enviados.

Também pare de fazer atualizações de IU, já que elas não serão vistas pelo usuário, e interrompa todas as tarefas que um usuário não quer que sejam executadas em segundo plano.

Frozen

No estado congelado, as tarefas congeláveis nas filas de tarefas ficam 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 que você interrompa os timers ou desative as conexões que, se congeladam, possam afetar outras guias abertas na mesma origem ou afetar a capacidade do navegador de colocar a página no cache de avanço e retorno.

Especificamente, é importante fazer o seguinte:

Também é preciso manter qualquer estado de visualização dinâmica (por exemplo, posição de rolagem em uma visualização em lista infinita) até sessionStorage (ou IndexedDB via commit()) que você gostaria de restaurar se a página fosse descartada e recarregada depois.

Se a página passar de congelada de volta para oculta, você poderá reabrir todas as conexões fechadas ou reiniciar qualquer pesquisa interrompida quando a página estava inicialmente congelada.

Terminated

Geralmente, não é necessário fazer nada 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 hidden antes de entrar no estado encerrado, é no estado oculto que a lógica de encerramento da sessão (por exemplo, persistência do estado do aplicativo e da geração de relatórios para análise) precisa ser executada.

Além disso, conforme mencionado nas recomendações para o estado oculto, é muito importante que os desenvolvedores percebam que a transição para o estado encerrado não pode ser detectada de maneira 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 descartado não pode ser observado pelos desenvolvedores no momento em que uma página é descartada. Isso ocorre porque as páginas geralmente são descartadas sob restrições de recursos. Na maioria dos casos, não é possível congelar uma página apenas para permitir que um script seja executado em resposta a um evento de descarte.

Como resultado, prepare-se para a possibilidade de descarte na mudança de oculta para congelada e, em seguida, poderá reagir à restauração de uma página descartada no tempo de carregamento da página marcando document.wasDiscarded.

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

APIs de ciclo de vida legadas que devem ser evitadas

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 indicador 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 é disparado em muitas situações típicas de descarregamento, incluindo o fechamento de uma guia no seletor de guias em dispositivos móveis ou o fechamento do app do navegador pelo seletor de apps.

Por esse motivo, é sempre melhor confiar no evento visibilitychange para determinar quando uma sessão termina e considerar o estado oculto 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 possam colocar páginas no cache de avanço e retorno para carregar os carregamentos de avanço e retorno mais rápidos.

Em todos os navegadores modernos, é recomendável sempre usar o evento pagehide para detectar possíveis descarregamentos de páginas (ou seja, o estado encerrado) em vez do evento unload. Se você precisar oferecer suporte ao Internet Explorer versões 10 e anteriores, detecte o evento pagehide e use unload apenas se o navegador não for compatível com 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 unload, já 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 mais recentes não têm essa restrição. No entanto, alguns navegadores, por precaução, não dispararão 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 um 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 disparado, o que afeta ainda mais a confiabilidade.

Uma diferença entre beforeunload e unload é que há usos legítimos de beforeunload. Por exemplo, quando você quiser avisar ao usuário que ele tem mudanças não salvas, ele será perdido se continuar descarregando a página.

Como há motivos válidos para usar beforeunload, recomendamos que você somente adicione beforeunload listeners quando um usuário tiver alterações não salvas e remova-os imediatamente após salvá-las.

Em outras palavras, não faça isso, já que ele 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 isso, já que ele só adiciona o listener beforeunload quando necessário e o remove quando não é:

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 os estados como discretos e mutuamente exclusivos. Como uma página pode ser carregada no estado ativo, passivo ou oculto e, como pode mudar de estado (ou até mesmo ser encerrada) antes de terminar o carregamento, um estado de carregamento separado não faz sentido nesse paradigma.

Minha página faz um trabalho importante quando está oculta. Como posso impedir que ela seja congelada ou descartada?

Há muitos motivos legítimos para que 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.

Há também situações em que pode ser arriscado para o Chrome descartar uma página, como um formulário com entrada de usuário não enviada ou um gerenciador beforeunload que avisa quando a página está descarregando.

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

  • Reproduzindo áudio
  • Como usar o WebRTC
  • Como atualizar o título da tabela ou o favicon
  • Mostrando alertas
  • Como enviar notificações push

Para conferir os recursos de lista atuais usados para determinar se uma guia pode ser congelada ou descartada com segurança, consulte: Heurística para congelamento e descarte 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 que alguns navegadores implementam, tornando o uso dos botões "Voltar" e "Avançar" mais rápido.

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

Para todas as intents e finalidades, esse congelamento é funcionalmente o mesmo que os navegadores fazem para economizar CPU/bateria. Por esse motivo, ele é considerado parte do estado do ciclo de vida congelado.

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

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

No futuro, vamos adicionar um método commit() a objetos IDBTransaction, o que oferecerá aos desenvolvedores uma maneira de realizar o que são transações somente de gravação efetivamente que não exigem callbacks. Em outras palavras, se o desenvolvedor estiver apenas gravando dados no IndexedDB e não estiver 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 suspensas, supondo que o banco de dados do IndexedDB já esteja aberto.

No entanto, para códigos que precisam funcionar atualmente, os desenvolvedores têm duas opções:

  • Use o armazenamento de sessão:o armazenamento de sessão é síncrono e persiste entre descartes de páginas.
  • Usar o IndexedDB no seu service worker: um service worker pode armazenar dados no IndexedDB depois que a página for encerrada ou descartada. No listener de eventos freeze ou pagehide, é possível enviar dados para o service worker via postMessage(), e o service worker pode processar o salvamento dos dados.

Como testar o app nos estados congelado e descartado

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

O Chrome descarta a interface
O Chrome descarta a interface

Isso garante que sua página processe corretamente os eventos freeze e resume, bem como a sinalização document.wasDiscarded quando as páginas são recarregadas após um descarte.

Resumo

Os desenvolvedores que quiserem respeitar os recursos do sistema nos dispositivos dos usuários precisam criar apps considerando os 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 esperaria

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