Experiências off-line mais completas com a API Periodic Background Sync

Sincronize os dados do seu app da Web em segundo plano para ter uma experiência parecida com o app

Você já esteve em alguma das seguintes situações?

  • Usar um trem ou metrô com conexão lenta ou inexistente
  • Foi limitado pela operadora depois de assistir muitos vídeos
  • Viver em um país onde a largura de banda tem dificuldade para acompanhar a demanda.

Se já sentiu, com certeza você já sentiu a frustração de fazer certas coisas na Web e se perguntou por que os apps específicos da plataforma funcionam melhor nesses cenários. Os apps específicos da plataforma podem buscar conteúdo novo, como artigos de notícias ou informações meteorológicas, com antecedência. Mesmo que não haja nenhuma rede no metrô, você ainda poderá ler as notícias.

A sincronização periódica em segundo plano permite que aplicativos da Web sincronizem dados periodicamente em segundo plano, aproximando os apps da Web do comportamento de um app específico da plataforma.

Testar

Você pode testar a sincronização periódica em segundo plano com o app de demonstração ao vivo. Antes de usá-lo, verifique se:

  • estiver usando o Chrome 80 ou mais recente;
  • Você instala o app da Web antes de ativar a sincronização periódica em segundo plano.

Conceitos e uso

A sincronização periódica em segundo plano permite mostrar conteúdo novo quando um Progressive Web App ou uma página apoiada por service worker é iniciado. Isso é feito por meio do download de dados em segundo plano quando o app ou a página não estão sendo usados. Isso impede que o conteúdo do app seja atualizado após a inicialização enquanto ele está sendo visualizado. Melhor ainda, isso impede que o app mostre um ícone de carregamento de conteúdo antes de atualizar.

Sem a sincronização periódica em segundo plano, os apps da Web precisam usar métodos alternativos para fazer o download de dados. Um exemplo comum é usar uma notificação push para ativar um service worker. O usuário é interrompido por uma mensagem como "novos dados disponíveis". A atualização dos dados é essencialmente um efeito colateral. Você ainda tem a opção de usar notificações push para atualizações realmente importantes, como notícias de última hora importantes.

A sincronização periódica em segundo plano é facilmente confundida com a sincronização em segundo plano. Embora tenham nomes semelhantes, os casos de uso são diferentes. Entre outras coisas, a sincronização em segundo plano é mais usada para reenviar dados a um servidor quando uma solicitação anterior falha.

Acertar o engajamento do usuário

Se feita incorretamente, a sincronização periódica em segundo plano pode desperdiçar os recursos dos usuários. Antes do lançamento, o Chrome passou por um período de teste para garantir que estava certo. Esta seção explica algumas das decisões de design que o Chrome tomou para tornar esse recurso o mais útil possível.

A primeira decisão de design do Chrome é que um app da Web só pode usar a sincronização periódica em segundo plano depois que uma pessoa o instala no dispositivo e o inicia como um aplicativo distinto. A sincronização periódica em segundo plano não está disponível no contexto de uma guia normal no Chrome.

Além disso, como o Chrome não quer apps da Web não utilizados ou raramente usados para consumir bateria ou dados sem custo financeiro, o Chrome projetou a sincronização periódica em segundo plano, de forma que os desenvolvedores terão que ganhar isso oferecendo valor aos usuários. Concretamente, o Chrome está usando uma pontuação de engajamento do site (about://site-engagement/) para determinar se e com que frequência as sincronizações periódicas em segundo plano podem acontecer para um determinado app da Web. Em outras palavras, um evento periodicsync não é disparado, a menos que a pontuação de engajamento seja maior que zero e o valor dele afeta a frequência com que o evento periodicsync é acionado. Isso garante que os únicos apps sincronizados em segundo plano sejam os que você está usando ativamente.

A sincronização periódica em segundo plano tem algumas semelhanças com as APIs e práticas existentes em plataformas conhecidas. Por exemplo, a sincronização única em segundo plano, bem como as notificações push, permitem que a lógica de um app da Web dure mais tempo (por meio do service worker) depois que uma pessoa fecha a página. Na maioria das plataformas, é comum que as pessoas instalem apps que acessam a rede periodicamente em segundo plano para oferecer uma experiência do usuário melhor para atualizações críticas, pré-busca de conteúdo, sincronização de dados e assim por diante. Da mesma forma, a sincronização periódica em segundo plano também amplia o ciclo de vida da lógica de um app da Web para que seja executada em períodos regulares durante o que pode ser de alguns minutos por vez.

Se o navegador permitia que isso ocorresse com frequência e sem restrições, isso poderia resultar em algumas preocupações de privacidade. Veja como o Chrome lidou com esse risco de sincronização periódica em segundo plano:

  • A atividade de sincronização em segundo plano ocorre apenas em uma rede a que o dispositivo se conectou anteriormente. O Chrome recomenda se conectar apenas a redes operadas por partes confiáveis.
  • Como em todas as comunicações pela Internet, a sincronização periódica em segundo plano revela os endereços IP do cliente, o servidor com que ele está se comunicando e o nome dele. Para reduzir essa exposição ao que seria se o app fosse sincronizado apenas quando estava em primeiro plano, o navegador limita a frequência das sincronizações em segundo plano de um app para se alinhar à frequência com que a pessoa usa esse app. Se a pessoa parar de interagir com frequência com o app, a sincronização periódica em segundo plano parará de ser acionada. Essa é uma melhoria líquida em relação ao status quo dos apps específicos da plataforma.

Quando ela pode ser usada?

As regras de uso variam de acordo com o navegador. Para resumir, o Chrome aplica os seguintes requisitos na sincronização periódica em segundo plano:

  • Uma pontuação de engajamento do usuário específica.
  • Presença de uma rede usada anteriormente.

O tempo das sincronizações não é controlado pelos desenvolvedores. A frequência de sincronização será alinhada à frequência com que o app é usado. No momento, apps específicos da plataforma não fazem isso. Ele também analisa o estado de energia e conectividade do dispositivo.

Quando ela deve ser usada?

Quando o service worker é ativado para processar um evento periodicsync, você tem a oportunidade de solicitar dados, mas não a obrigação de fazer isso. Ao processar o evento, considere as condições de rede e o armazenamento disponível e faça o download de diferentes quantidades de dados em resposta. Você pode usar os seguintes recursos para ajudar:

Permissões

Depois que o service worker estiver instalado, use a API Permissions para consultar periodic-background-sync. É possível fazer isso em uma janela ou em um contexto de service worker.

const status = await navigator.permissions.query({
  name: 'periodic-background-sync',
});
if (status.state === 'granted') {
  // Periodic background sync can be used.
} else {
  // Periodic background sync cannot be used.
}

Como registrar uma sincronização periódica

Como já mencionado, a sincronização periódica em segundo plano requer um service worker. Recupere um PeriodicSyncManager usando ServiceWorkerRegistration.periodicSync e chame register() nele. O registro requer uma tag e um intervalo mínimo de sincronização (minInterval). A tag identifica a sincronização registrada para que várias sincronizações possam ser registradas. No exemplo abaixo, o nome da tag é 'content-sync' e minInterval é um dia.

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  try {
    await registration.periodicSync.register('content-sync', {
      // An interval of one day.
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch (error) {
    // Periodic background sync cannot be used.
  }
}

Como verificar um registro

Chame periodicSync.getTags() para recuperar uma matriz de tags de registro. O exemplo abaixo usa nomes de tags para confirmar se a atualização do cache está ativa e evitar novas atualizações.

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  const tags = await registration.periodicSync.getTags();
  // Only update content if sync isn't set up.
  if (!tags.includes('content-sync')) {
    updateContentOnPageLoad();
  }
} else {
  // If periodic background sync isn't supported, always update.
  updateContentOnPageLoad();
}

Também é possível usar getTags() para mostrar uma lista de registros ativos na página de configurações do seu app da Web para que os usuários possam ativar ou desativar tipos específicos de atualizações.

Como responder a um evento periódico de sincronização em segundo plano

Para responder a um evento periódico de sincronização em segundo plano, adicione um manipulador de eventos periodicsync ao service worker. O objeto event transmitido a ele conterá um parâmetro tag correspondente ao valor usado durante o registro. Por exemplo, se uma sincronização periódica em segundo plano for registrada com o nome 'content-sync', então event.tag será 'content-sync'.

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'content-sync') {
    // See the "Think before you sync" section for
    // checks you could perform before syncing.
    event.waitUntil(syncContent());
  }
  // Other logic for different tags as needed.
});

Como cancelar o registro de uma sincronização

Para encerrar uma sincronização registrada, chame periodicSync.unregister() com o nome da sincronização que você quer cancelar.

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  await registration.periodicSync.unregister('content-sync');
}

Interfaces

Confira um breve resumo das interfaces fornecidas pela API Periodic Background Sync.

  • PeriodicSyncEvent. São transmitidos ao manipulador de eventos ServiceWorkerGlobalScope.onperiodicsync no momento da escolha do navegador.
  • PeriodicSyncManager. Registra e cancela o registro de sincronizações periódicas e fornece tags para sincronizações registradas. Recupere uma instância dessa classe da propriedade ServiceWorkerRegistration.periodicSync.
  • ServiceWorkerGlobalScope.onperiodicsync. Registra um gerenciador para receber o PeriodicSyncEvent.
  • ServiceWorkerRegistration.periodicSync. Retorna uma referência para o PeriodicSyncManager.

Exemplo

Atualizando conteúdo

O exemplo a seguir usa uma sincronização periódica em segundo plano para fazer o download e armazenar em cache artigos atualizados para um site de notícias ou blog. Observe o nome da tag, que indica o tipo de sincronização ('update-articles'). A chamada para updateArticles() é encapsulada em event.waitUntil() para que o service worker não seja encerrado antes do download e do armazenamento dos artigos.

async function updateArticles() {
  const articlesCache = await caches.open('articles');
  await articlesCache.add('/api/articles');
}

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'update-articles') {
    event.waitUntil(updateArticles());
  }
});

Adicionar sincronização periódica em segundo plano a um app da Web

Esse conjunto de alterações foi necessário para adicionar a sincronização periódica em segundo plano a um PWA atual. Este exemplo inclui várias log statements úteis que descrevem o estado da sincronização periódica em segundo plano no app da Web.

Depuração

Pode ser um desafio ter uma visualização completa da sincronização periódica em segundo plano durante o teste local. As informações sobre registros ativos, intervalos de sincronização aproximados e registros de eventos de sincronização anteriores fornecem contexto valioso durante a depuração do comportamento do app da Web. Felizmente, você pode encontrar todas essas informações em um recurso experimental no Chrome DevTools.

Gravando atividade local

A seção Periodic Background Sync do DevTools é organizada em torno dos principais eventos do ciclo de vida periódico da sincronização em segundo plano: registro para sincronização, execução de uma sincronização em segundo plano e cancelamento de registro. Para ver informações sobre esses eventos, clique em Start recording.

O botão de gravação no DevTools
O botão de gravação no DevTools

Durante a gravação, as entradas vão aparecer no DevTools correspondentes aos eventos, com contexto e metadados registrados para cada um.

Exemplo de dados de sincronização em segundo plano registrados e periódicos
Um exemplo de dados de sincronização periódicos gravados em segundo plano

Depois de ativar a gravação uma vez, ela permanecerá ativada por até três dias, permitindo que o DevTools capture informações de depuração locais sobre sincronizações em segundo plano que possam ocorrer, mesmo horas depois.

Como simular eventos

Embora a gravação de atividades em segundo plano possa ser útil, há momentos em que é interessante testar o gerenciador periodicsync imediatamente, sem esperar que um evento seja disparado na cadência normal.

Faça isso na seção Service Workers do painel "Application" no Chrome DevTools. O campo Sincronização periódica permite fornecer uma tag para o evento usar e acioná-la quantas vezes você quiser.

A seção "Service Workers" do painel do Aplicativo mostra um campo de texto e um botão "Sincronização periódica".

Como usar a interface do DevTools

A partir do Chrome 81, você verá a seção Sincronização periódica em segundo plano no painel Aplicativo do DevTools.

O painel "Application" mostrando a seção "Periodic Background Sync"