Publicado em: 8 de dezembro de 2015
A sincronização em segundo plano é uma API da Web que permite adiar ações até que o usuário tenha uma conectividade estável. Isso ajuda você a permitir que os usuários enviem os arquivos que quiserem assim que for possível.
O problema
"A Internet é uma ótima opção para perder tempo." Sem perder tempo na Internet, não saberíamos que gatos não gostam de flores, que camaleões adoram bolhas ou que Eric Bidelman é um herói do minigolfe do fim dos anos 90.
Mas às vezes, só às vezes, não queremos perder tempo. A experiência ideal do usuário é mais parecida com isto:
- Smartphone fora do bolso.
- Alcançar uma meta secundária.
- Coloque o smartphone de volta no bolso.
- Retomar a vida.
Infelizmente, essa experiência é frequentemente prejudicada por uma conexão ruim. Todos nós já passamos por esta situação. Você está olhando para uma tela branca ou um spinner e sabe que deveria desistir e seguir em frente, mas espera mais 10 segundos por precaução. Após esses 10 segundos? Nada
Mas por que desistir agora? Você já investiu tempo, então sair sem nada seria um desperdício. Por isso, você continua esperando. Nesse momento, você quer desistir, mas sabe que, se fizer isso, vai ser um segundo antes de tudo carregar se você tivesse esperado.
Os service workers resolvem a parte do carregamento da página, permitindo que você disponibilize conteúdo de um cache. Mas e quando a página precisa enviar algo para o servidor?
No momento, se o usuário clicar em "Enviar" em uma mensagem, ele precisa esperar um spinner até que ele seja concluído. Se eles tentarem sair ou fechar a guia, vamos usar onbeforeunload para mostrar uma mensagem como "Não, preciso que você olhe mais um pouco para este spinner. Desculpe". Se o usuário não tiver conexão, vamos dizer: "Desculpe, você precisa voltar mais tarde e tentar de novo".
A sincronização em segundo plano ajuda você a fazer melhor.
A solução
O vídeo a seguir mostra o Emojoy, uma demonstração de chat apenas com emojis. É um App Web Progressivo e funciona priorizando o modo off-line. O app usa mensagens e notificações push e sincronização em segundo plano.
Se o usuário tentar enviar uma mensagem sem conectividade, ela será enviada em segundo plano assim que a conexão for restabelecida.
A capacidade de enviar em segundo plano como essa também gera uma melhoria na performance percebida. O app não precisa fazer um grande alarde sobre o envio da mensagem, então ele pode adicionar a mensagem à saída imediatamente.
A sincronização em segundo plano está disponível a partir do Chrome 49.
Como solicitar uma sincronização em segundo plano
No verdadeiro estilo da Web extensível, esse é um recurso de baixo nível que oferece a liberdade de fazer o que você precisa. Você pede que um evento seja acionado quando o usuário tiver conectividade, o que é imediato se ele já tiver conectividade. Em seguida, você detecta esse evento e faz o que for necessário.
Assim como as mensagens push, ele 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 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. doSomeStuff() precisa retornar uma promessa indicando o sucesso ou a falha do que está tentando fazer. Se for concluída, a sincronização será concluída.
Se ela falhar, outra sincronização será programada para tentar de novo. As novas tentativas de sincronização também aguardam a conectividade e usam uma espera exponencial.
O nome da tag da sincronização ("myFirstSync" no exemplo) precisa ser exclusivo para uma determinada sincronização. Se você registrar uma sincronização usando a mesma tag de uma sincronização pendente, ela será unida à sincronização atual. Isso significa que você pode se registrar para uma sincronização "clear-outbox" sempre que o usuário enviar uma mensagem, mas se ele enviar cinco mensagens off-line, você só receberá uma sincronização quando ele ficar on-line. Para receber cinco eventos de sincronização separados, use tags exclusivas.
Confira uma demonstração que usa o evento de sincronização para mostrar uma notificação.
Usos da sincronização em segundo plano
O ideal é usá-lo para programar o envio de dados importantes além da vida útil da página. Mensagens de chat, e-mails, atualizações de documentos, mudanças de configurações, uploads de fotos ou qualquer conteúdo que você queira alcançar o servidor, mesmo que o usuário saia ou feche a guia. A página pode armazenar esses dados em uma caixa de saída no IndexedDB, e o service worker os recupera e envia.
No entanto, também é possível usá-lo para buscar pequenos bits de dados.
Demonstração da Wikipédia off-line
Esta é a demonstração da Wikipedia off-line que criei para o Supercharging Page Load. Desde então, adicionei um pouco de magia de sincronização em segundo plano.
Faça um teste:
- Mantenha o navegador aberto nessa guia.
- Fique off-line com o modo avião ou desativando o Wi-Fi.
- Clique em um link para outro artigo.
- Você vai receber uma mensagem informando que a página não foi carregada. Isso também vai aparecer se a página demorar um pouco para carregar.
- Concorde com as notificações.
- Feche o navegador.
- Modo on-line
- Você vai receber uma notificação quando o artigo for baixado, armazenado em cache e estiver pronto para leitura.
Usando esse padrão, o usuário pode colocar o smartphone no bolso e seguir a vida, sabendo que o dispositivo vai alertar quando encontrar o que ele queria.
Permissões
As demonstrações que mostrei 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 tem uma página aberta no site. Por isso, exigir permissão do usuário seria uma experiência ruim. Em vez disso, estamos limitando quando as sincronizações podem ser registradas e acionadas para evitar abusos. Exemplo:
- Só é possível se inscrever em um evento de sincronização quando o usuário tem uma janela aberta para o site.
- O tempo de execução do evento é limitado. Portanto, não é possível usá-los para enviar pings a um servidor a cada x segundos, minerar bitcoins ou qualquer outra coisa.
É claro que essas restrições podem ser flexibilizadas ou reforçadas com base no uso no mundo real.
Aprimoramento progressivo
Enquanto aguardamos a sincronização em segundo plano se tornar um recurso básico, você pode usá-la como um aprimoramento progressivo:
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, poste 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 é lançar a sincronização em segundo plano em 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, você pode solicitar um evento restrito por intervalo de tempo, estado da bateria e estado da rede. Isso exige permissão do usuário e depende do navegador para saber quando e com que frequência esses eventos são disparados. 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ê esse site às 7h, então a sincronização será feita diariamente às 6h50. Essa ideia está um pouco mais distante do que a sincronização única, mas ela vai chegar.
Estamos trazendo gradualmente padrões de sucesso do Android e do iOS para a Web, sem perder o que torna a Web incrível.