Apresentamos a Sincronização em segundo plano

Jake Archibald
Jake Archibald

Sincronização em segundo plano é uma nova API da Web que permite adiar ações até que o usuário tenha conectividade. Isso garante que tudo o que o usuário quiser enviar seja realmente enviado.

O problema

A Internet é um ótimo lugar para perder tempo. Sem perder tempo na Internet, não saberíamos que gatos não gostam de flores, cameleons amam bolhas ou que nosso Eric Bidelman é um herói do putt do final dos anos 90.

Mas, às vezes, não queremos perder tempo. O usuário desejado é mais ou menos assim:

  1. Smartphone fora do bolso.
  2. Atingir um objetivo menor.
  3. Smartphone de volta no bolso.
  4. Retomar.

Infelizmente, essa experiência costuma ser prejudicada por uma conectividade ruim. Todos nós já sentimos isso. Você está olhando para uma tela branca ou um ícone de carregamento e sabe que deveria apenas desistir e seguir com sua vida, mas precisa dar mais 10 segundos, caso precise. Depois desses 10 segundos? Nada

Mas por que desistir agora? Você já investiu tempo, então ir embora sem nada seria um desperdício, então continua esperando. A essa altura você quer desistir, mas sabe que o segundo que faz isso é o segundo antes de tudo ter sido carregado se você tivesse esperado.

Os service workers resolvem a parte de carregamento da página permitindo que você exiba o conteúdo de um cache. Mas e quando a página precisa enviar algo ao servidor?

No momento, se o usuário clicar em "enviar" em uma mensagem. Ele precisa olhar para um ícone de carregamento até que o processo seja concluído. Se eles tentarem sair ou fechar a guia, vamos usar o onbeforeunload para mostrar uma mensagem como: "Não, preciso que você olhe para este ícone de carregamento um pouco mais. Desculpe". Se o usuário não tiver uma conexão, ele receberá uma mensagem: "Você precisa voltar mais tarde e tentar novamente".

Isso é absurdo. A sincronização em segundo plano permite fazer melhor.

A solução

O vídeo a seguir mostra Emojoy, um chat de demonstração apenas de emojis. Ele é um Progressive Web App e funciona primeiro off-line. O app usa mensagens push e notificações, além de sincronização em segundo plano.

Se o usuário tentar enviar uma mensagem quando não tiver conectividade, felizmente a mensagem será enviada em segundo plano assim que tiver conectividade.

A partir de março de 2016, a sincronização em segundo plano está disponível no Chrome a partir da versão 49. Para isso, siga as etapas abaixo:

  1. Abra o Emojoy.
  2. Fique off-line (usando o modo avião ou visite sua gaiola de Faraday local).
  3. Digite uma mensagem.
  4. Volte para a tela inicial. Se quiser, feche a guia ou o navegador.
  5. Fique on-line.
  6. A mensagem é enviada em segundo plano.

Poder enviar em segundo plano dessa forma também gera uma melhoria de desempenho percebida. O aplicativo não precisa se preocupar com o envio da mensagem, então ele pode adicionar a mensagem à saída imediatamente.

Como solicitar uma sincronização em segundo plano

No estilo verdadeiro da Web extensível, trata-se de uma recurso de baixo nível que dá a você a liberdade de fazer o que precisa. Você pede uma a ser acionado quando o usuário tiver conectividade, o que é imediato se o usuário já tem conectividade. Então, você ouve esse evento e faz o que quer o que precisamos fazer.

Assim como nas mensagens push, ela usa um service worker como destino do evento, o que permite que ele funcione quando a página não está aberta. Para começar, registre-se para uma sincronização em uma página:

// Register your service worker:
navigator.serviceWorker.register('/sw.js');

// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});
 ```

Then listen for the event in `/sw.js`:

```js
self.addEventListener('sync', function(event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

Pronto. Acima, doSomeStuff() retorna uma promessa que indica o sucesso ou a falha do que quer que esteja tentando fazer. Em caso afirmativo, a sincronização estará concluída. Em caso de falha, outra sincronização será agendada para uma nova tentativa. Novas sincronizações também aguardam a conectividade e empregam uma espera exponencial.

O nome da tag da sincronização ("myFirstSync" no exemplo acima) deve ser exclusivo para cada sincronização. Se você registrar uma sincronização usando a mesma tag de uma sincronização pendente, ela será mesclada com a sincronização atual. Isso significa que você pode se registrar para uma "caixa de saída" sincronizar sempre que o usuário enviar uma mensagem. Porém, se ele enviar cinco mensagens enquanto estiver off-line, você terá apenas uma sincronização quando ele ficar on-line. Se você quiser cinco eventos de sincronização separados, basta usar tags exclusivas.

Veja uma demonstração simples que faz o mínimo: ele usa o evento de sincronização para mostrar uma notificação.

Para que posso usar a sincronização em segundo plano?

O ideal é usá-lo para agendar o envio de dados importantes para você além da vida útil da página. Mensagens de bate-papo, e-mails, atualizações em documentos, alterações de configurações, uploads de fotos... qualquer coisa que você queira alcançar ao servidor, mesmo que o usuário saia ou feche a guia. A página poderia armazená-los em uma "caixa de saída" que o service worker os recuperaria e enviaria.

Mas você também pode usá-lo para buscar pequenos pedaços de dados...

Outra demonstração!

Esta é a demonstração da Wikipédia off-line que criei para Melhorar o carregamento da página. Depois disso, adicionei um toque mágico de sincronização em segundo plano.

Faça um teste. Verifique se você está usando o Chrome 49 ou mais recente. Depois:

  1. Acesse qualquer artigo, talvez o Chrome.
  2. Fique off-line, seja usando o modo avião ou entre em contato com uma péssima operadora de celular como a minha.
  3. Clique em um link para outro artigo.
  4. Você receberá a mensagem de que a página falhou ao carregar (isso também aparecerá se a página levar um tempo para carregar).
  5. Concorde com as notificações.
  6. Feche o navegador.
  7. Modo on-line
  8. Você vai receber uma notificação quando o artigo for transferido por download, armazenado em cache e pronto para visualização.

Usando esse padrão, o usuário pode colocar o smartphone no bolso e seguir com a vida, sabendo que o smartphone o alertará quando for buscado.

Permissões

As demonstrações apresentadas usam notificações da Web, que exigem permissão, mas a sincronização em segundo plano não.

Os eventos de sincronização geralmente são concluídos enquanto o usuário está com uma página aberta no site. Portanto, exigir a permissão do usuário seria uma experiência ruim. Em vez disso, limitamos o momento em que as sincronizações podem ser registradas e acionadas para evitar abusos. Exemplo:

  • Você só pode se inscrever em um evento de sincronização quando o usuário está com uma janela aberta no site.
  • O tempo de execução do evento é limitado, portanto não é possível usá-los para dar ping em um servidor a cada x segundos, minerar bitcoins ou qualquer outra coisa.

É claro que essas restrições podem diminuir ou diminuir com base no uso no mundo real.

Aprimoramento progressivo

Vai levar algum tempo até que todos os navegadores ofereçam suporte à sincronização em segundo plano, principalmente porque o Safari e o Edge ainda não têm suporte aos service workers. Mas o aprimoramento progressivo ajuda aqui:

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navigator.serviceWorker.ready.then(function(reg) {
    return reg.sync.register('tag-name');
  }).catch(function() {
    // system was unable to register for a sync,
    // this could be an OS-level restriction
    postDataFromThePage();
  });
} else {
  // serviceworker/sync not supported
  postDataFromThePage();
}

Se os service workers ou a sincronização em segundo plano não estiverem disponíveis, basta publicar o conteúdo da página, como você faria hoje.

Vale a pena usar a sincronização em segundo plano mesmo que o usuário pareça ter uma boa conectividade, porque ela protege você contra navegações e fechamentos de guias durante o envio de dados.

O futuro

Nosso objetivo é fornecer a sincronização em segundo plano para uma versão estável do Chrome no primeiro semestre de 2016, enquanto trabalhamos em uma variante, a "sincronização periódica em segundo plano". Com a sincronização periódica em segundo plano, é possível solicitar um evento restrito por intervalo de tempo, estado da bateria e da rede. Isso exige a permissão do usuário, e também depende do navegador determinar quando e com que frequência esses eventos são acionados. Em outras palavras, um site de notícias pode solicitar a sincronização a cada hora, mas o navegador pode saber que você só lê o site às 7h, de modo que a sincronização é acionada diariamente às 6h50. Essa ideia está um pouco mais distante do que uma sincronização única, mas está a caminho.

Aos poucos, estamos trazendo padrões de sucesso do Android e do iOS para a Web, sem deixar de manter o que torna a Web incrível!