Este codelab mostra como implementar uma experiência de pesquisa resiliente com o Workbox. O app de demonstração usado contém uma caixa de pesquisa que chama um endpoint do servidor e redireciona o usuário para uma página HTML básica.
Medir
Antes de adicionar otimizações, é sempre bom analisar o estado atual do aplicativo. Verifique como o site se comporta quando fica off-line:
- Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
- Clique na guia Rede.
- Abra o Chrome DevTools e selecione o painel "Rede".
- Na lista suspensa de limitação, selecione Off-line.
- No app de demonstração, digite uma consulta de pesquisa e clique no botão Pesquisar.
A página de erro padrão do navegador é mostrada:

Fornecer uma resposta substituta
O service worker contém o código para adicionar a página off-line à lista de pré-cache, para que ela possa sempre ser armazenada em cache no evento install do service worker.
Normalmente, você precisaria instruir o Workbox a adicionar esse arquivo à lista de pré-cache no momento da criação, integrando a biblioteca à ferramenta de build escolhida (por exemplo, webpack ou gulp).
Para simplificar, já fizemos isso para você. O código a seguir em public/sw.js faz isso:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Em seguida, adicione o código para usar a página off-line como uma resposta alternativa:
- Para conferir a origem, pressione Ver origem.
- Adicione o seguinte código à parte de baixo de public/sw.js:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
  switch (event.request.destination) {
    case 'document':
      return caches.match(FALLBACK_HTML_URL);
      break;
    default:
      return Response.error();
  }
});
O código realiza as ações a seguir:
- Define uma estratégia somente de rede padrão que será aplicada a todas as solicitações.
- Declara um gerenciador de erros global chamando workbox.routing.setCatchHandler()para gerenciar solicitações com falha. Quando as solicitações forem para documentos, uma página HTML off-line substituta será retornada.
Para testar essa funcionalidade:
- Volte para a outra guia que está executando o app.
- Defina a lista suspensa Limitação de volta para On-line.
- Pressione o botão Voltar do Chrome para voltar à página de pesquisa.
- Verifique se a caixa de seleção Desativar cache no DevTools está desmarcada.
- Toque e pressione o botão Atualizar do Chrome e selecione Limpar cache e atualizar de forma forçada para garantir que o service worker seja atualizado.
- Defina a lista suspensa Limitação novamente como Off-line.
- Digite uma consulta de pesquisa e clique no botão Pesquisar novamente.
A página HTML de substituição é mostrada:

Solicitar permissão de notificações
Para simplificar, a página off-line em views/index_offline.html já contém o código para solicitar permissões de notificação em um bloco de script na parte de baixo:
function requestNotificationPermission(event) {
  event.preventDefault();
  Notification.requestPermission().then(function (result) {
    showOfflineText(result);
  });
}
O código realiza as ações a seguir:
- Quando o usuário clica em inscrever-se para receber notificações, a função requestNotificationPermission()é chamada, que chamaNotification.requestPermission()para mostrar a solicitação de permissão padrão do navegador. A promessa é resolvida com a permissão escolhida pelo usuário, que pode sergranted,deniedoudefault.
- Transmite a permissão resolvida para showOfflineText()e mostra o texto adequado ao usuário.
Manter consultas off-line e tentar de novo quando estiver on-line
Em seguida, implemente a Sincronização em segundo plano do Workbox para manter as consultas off-line. Assim, elas podem ser repetidas quando o navegador detectar que a conectividade foi restabelecida.
- Abra public/sw.jspara edição.
- Adicione o seguinte código ao final do arquivo:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
  maxRetentionTime: 60,
  onSync: async ({queue}) => {
    let entry;
    while ((entry = await queue.shiftRequest())) {
      try {
        const response = await fetch(entry.request);
        const cache = await caches.open('offline-search-responses');
        const offlineUrl = `${entry.request.url}¬ification=true`;
        cache.put(offlineUrl, response);
        showNotification(offlineUrl);
      } catch (error) {
        await this.unshiftRequest(entry);
        throw error;
      }
    }
  },
});
O código realiza as ações a seguir:
- O workbox.backgroundSync.Plugincontém a lógica para adicionar solicitações com falha a uma fila para que possam ser repetidas mais tarde. Essas solicitações serão mantidas no IndexedDB.
- maxRetentionTimeindica o tempo que uma solicitação pode ser repetida. Neste caso, escolhemos 60 minutos (após os quais ele será descartado).
- onSyncé a parte mais importante desse código. Esse callback será chamado quando a conexão voltar para que as solicitações enfileiradas sejam recuperadas e buscadas da rede.
- A resposta da rede é adicionada ao cache offline-search-responses, anexando o parâmetro de consulta¬ification=true. Assim, essa entrada de cache pode ser selecionada quando um usuário clica na notificação.
Para integrar a sincronização em segundo plano ao seu serviço, defina uma estratégia NetworkOnly para solicitações ao URL de pesquisa (/search_action) e transmita o bgSyncPlugin definido anteriormente. Adicione o seguinte código à parte de baixo de public/sw.js:
const matchSearchUrl = ({url}) => {
  const notificationParam = url.searchParams.get('notification');
  return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
  matchSearchUrl,
  new workbox.strategies.NetworkOnly({
    plugins: [bgSyncPlugin],
  }),
);
Isso informa ao Workbox para sempre acessar a rede e, quando as solicitações falharem, usar a lógica de sincronização em segundo plano.
Em seguida, adicione o código a seguir à parte de baixo de public/sw.js para definir uma estratégia de cache para solicitações de notificações. Use uma estratégia CacheFirst para que eles possam ser veiculados do cache.
const matchNotificationUrl = ({url}) => {
  const notificationParam = url.searchParams.get('notification');
  return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
  new workbox.strategies.CacheFirst({
     cacheName: 'offline-search-responses',
  })
);
Por fim, adicione o código para mostrar notificações:
function showNotification(notificationUrl) {
  if (Notification.permission) {
     self.registration.showNotification('Your search is ready!', {
        body: 'Click to see you search result',
        icon: '/img/workbox.jpg',
        data: {
           url: notificationUrl
        }
     });
  }
}
self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  event.waitUntil(
     clients.openWindow(event.notification.data.url)
  );
});
Testar o recurso
- Volte para a outra guia que está executando o app.
- Defina a lista suspensa Limitação de volta para On-line.
- Pressione o botão Voltar do Chrome para voltar à página de pesquisa.
- Toque e pressione o botão Atualizar do Chrome e selecione Limpar cache e atualizar de forma forçada para garantir que o service worker seja atualizado.
- Defina a lista suspensa Limitação novamente como Off-line.
- Digite uma consulta de pesquisa e clique no botão Pesquisar novamente.
- Clique em Inscrever-se para receber notificações.
- Quando o Chrome perguntar se você quer conceder permissão ao app para enviar notificações, clique em Permitir.
- Digite outra consulta de pesquisa e clique no botão Pesquisar novamente.
- Defina a lista suspensa Limitação de volta para On-line.
Quando a conexão for restabelecida, uma notificação vai aparecer:

Conclusão
O Workbox oferece muitos recursos integrados para tornar seus PWAs mais resilientes e envolventes. Neste codelab, você aprendeu a implementar a API Background Sync usando a abstração do Workbox para garantir que as consultas off-line dos usuários não sejam perdidas e possam ser repetidas quando a conexão for restabelecida. A demonstração é um app de pesquisa simples, mas você pode usar uma implementação semelhante para cenários e casos de uso mais complexos, incluindo apps de chat, postagem de mensagens em uma rede social etc.
 
 
        
        