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

Sincronizar os dados do seu web app em segundo plano para uma experiência mais parecida com um app

Você já passou por alguma das seguintes situações?

  • Andar de trem ou metrô com conectividade instável ou sem conectividade
  • Ter sido limitado pela sua operadora depois de assistir muitos vídeos
  • Morar em um país onde a largura de banda tem dificuldade para acompanhar a demanda

Se sim, você certamente sentiu a frustração de fazer certas coisas na Web e se perguntou por que os apps específicos da plataforma geralmente se saem melhor nesses cenários. Os apps específicos da plataforma podem buscar conteúdo novo, como artigos de notícias ou informações sobre o clima, com antecedência. Mesmo que não haja rede no metrô, você ainda pode 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

O DevTools Tips é um PWA que usa a API Periodic Background Sync. O PWA de dicas do DevTools busca novas dicas de ferramentas para desenvolvedores todos os dias e as armazena em cache. Assim, os usuários podem acessar as dicas na próxima vez que abrirem o app, estejam on-line ou não. Instale o app para que a API Periodic Background Sync fique disponível.

Acesse o código-fonte no GitHub. Em especial, o app registra a sincronização periódica na função registerPeriodicSync(). O código do service worker é onde o app detecta o evento periodicsync.

Conceitos e uso

A sincronização periódica em segundo plano permite mostrar conteúdo atualizado quando um app da Web progressivo ou uma página com suporte de service worker é iniciada. Para isso, ele faz o download de dados em segundo plano quando o app ou a página não está sendo usado. Isso impede que o conteúdo do app seja atualizado após o lançamento enquanto está sendo visualizado. Melhor ainda, ele impede que o app mostre um spinner de conteúdo antes da atualização.

Sem a sincronização periódica em segundo plano, os apps da Web precisam usar métodos alternativos para baixar 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 significativas.

A sincronização periódica em segundo plano pode ser 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 comumente usada para reenviar dados a um servidor quando uma solicitação anterior falhou.

Como acertar no engajamento do usuário

Se feita de maneira incorreta, a sincronização periódica em segundo plano pode desperdiçar os recursos dos usuários. Antes de lançar, o Chrome passou por um período de teste para garantir que estava tudo 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 web app 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 que apps da Web não usados ou raramente usados consumam bateria ou dados sem necessidade, ele projetou a sincronização periódica em segundo plano para que os desenvolvedores precisem merecê-la oferecendo valor aos usuários. Especificamente, o Chrome usa uma pontuação de engajamento no site (about://site-engagement/) para determinar se e com que frequência as sincronizações periódicas em segundo plano podem ocorrer para um determinado web app. Em outras palavras, um evento periodicsync não será acionado, a menos que a pontuação de engajamento seja maior que zero, e o valor dela afeta a frequência com que o evento periodicsync é acionado. Isso garante que apenas os apps que você está usando ativamente sejam sincronizados em segundo plano.

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

Se o navegador permitisse que isso acontecesse com frequência e sem restrições, poderia resultar em problemas de privacidade. Veja como o Chrome abordou esse risco para a sincronização periódica em segundo plano:

  • A atividade de sincronização em segundo plano só ocorre em uma rede a que o dispositivo já se conectou. O Chrome recomenda que você se conecte 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, do servidor com que ele está se comunicando e o nome do servidor. Para reduzir essa exposição a aproximadamente o que seria se o app só sincronizasse quando estivesse 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 em apps específicos da plataforma.

Quando ela pode ser usada?

As regras de uso variam de acordo com o navegador. Resumindo, o Chrome impõe os seguintes requisitos à 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 vai se alinhar com a frequência de uso do app. (Os apps específicos da plataforma não fazem isso.) Ele também considera o estado de energia e conectividade do dispositivo.

Quando ele deve ser usado?

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 baixe quantidades diferentes de dados em resposta. Você pode usar os seguintes recursos para ajudar:

Permissões

Depois que o service worker for 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.
}

Registrar uma sincronização periódica

Como já foi dito, a sincronização periódica em segundo plano exige um service worker. Recupere um PeriodicSyncManager usando ServiceWorkerRegistration.periodicSync e chame register() nele. O registro exige 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 a seguir, o nome da tag é 'content-sync' e o 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.
  }
}

Verificar um registro

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

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();
}

Você também pode 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.

Responder a um evento de sincronização periódica em segundo plano

Para responder a um evento de sincronização periódica em segundo plano, adicione um manipulador de eventos periodicsync ao service worker. O objeto event transmitido a ele vai conter um parâmetro tag que corresponde ao valor usado durante o registro. Por exemplo, se uma sincronização periódica em segundo plano foi 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.
});

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 o registro.

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

Interfaces

Confira um resumo rápido das interfaces fornecidas pela API Periodic Background Sync.

  • PeriodicSyncEvent. Transmitido ao manipulador de eventos ServiceWorkerGlobalScope.onperiodicsync em um momento escolhido pelo 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 manipulador para receber o PeriodicSyncEvent.
  • ServiceWorkerRegistration.periodicSync. Retorna uma referência ao PeriodicSyncManager.

Exemplo

As seções a seguir mostram alguns exemplos de uso da API Periodic Background Sync.

Atualizar conteúdo

O exemplo a seguir usa a sincronização periódica em segundo plano para baixar e armazenar em cache artigos atualizados de 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 que os artigos sejam baixados e armazenados.

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 web app

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

Depurar a API Periodic Background Sync

Pode ser difícil ter uma visão completa da sincronização periódica em segundo plano ao testar localmente. Informações sobre registros ativos, intervalos aproximados de sincronização e registros de eventos de sincronização anteriores fornecem um contexto valioso ao depurar o comportamento do seu web app. Felizmente, você pode encontrar todas essas informações em um recurso experimental do Chrome DevTools.

Registrar atividade local

A seção Sincronização periódica em segundo plano do DevTools é organizada em torno de eventos principais no ciclo de vida da sincronização periódica em segundo plano: registro para sincronização, execução de uma sincronização em segundo plano e cancelamento do registro. Para saber mais sobre esses eventos, clique em Iniciar gravação.

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 periódica em segundo plano gravados
Exemplo de dados gravados de sincronização periódica em segundo plano

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

Simular eventos

Embora gravar a atividade em segundo plano possa ser útil, há momentos em que você quer testar o manipulador periodicsync imediatamente, sem esperar que um evento seja disparado na cadência normal.

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

A seção "Service Workers" do painel "Application" mostra um campo de texto e um botão "Periodic Sync".
"A seção 'Service Workers' do painel 'Application' mostra um campo de texto e um botão 'Periodic Sync'."

Uso da interface do DevTools

Você vai encontrar uma seção Sincronização periódica em segundo plano no painel Aplicativo do DevTools.

O painel "Application" mostrando a seção "Periodic Background Sync"
A seção "Sincronização periódica em segundo plano"