Workbox

Manter o service worker e a lógica de armazenamento em cache pode ser um desafio à medida que seu PWA cresce. O Workbox (em inglês) é um conjunto de bibliotecas de código aberto para ajudar com isso. A caixa de trabalho encapsula as APIs de nível inferior, como a API Service Worker e a API Cache Storage, e expõe mais interfaces voltadas para o desenvolvedor.

Algumas tarefas que podem ajudar são a correspondência de estratégias de armazenamento em cache com caminhos (ou padrões de roteamento), o trabalho com streams e o uso de recursos como sincronização em segundo plano com substitutos adequados.

O Workbox ajuda você a gerenciar suas necessidades de armazenamento em cache e veiculação de recursos. É também a biblioteca mais usada para service workers. usada por 54% dos sites para dispositivos móveis e em muitas ferramentas de build e CLIs, incluindo Angular CLI, Create-React-App e Vue CLI. Também existem plug-ins para a maioria das outras bibliotecas e frameworks, como o Next.js.

54%

Sites para dispositivos móveis com service workers usam a biblioteca Workbox

Módulos de caixa de trabalho

O Workbox inclui várias bibliotecas, chamadas de módulos internamente, cada uma focada em um aspecto diferente do gerenciamento de recursos e do comportamento do service worker.

Os módulos de caixa de trabalho funcionam em diferentes contextos, como:

  • Em um contexto de service worker: você importa os módulos necessários e os usa do seu arquivo do service worker, por exemplo, para ajudar a gerenciar o armazenamento em cache e exibir arquivos com diferentes estratégias.
  • No contexto principal do window: ajudar a registrar um service worker e se comunicar com ele
  • Como parte de um sistema de build: por exemplo, webpack, para criar um manifesto dos seus recursos ou até mesmo gerar todo o service worker.

Alguns módulos conhecidos são:

  • workbox-routing: quando o service worker intercepta solicitações, este módulo encaminha essas solicitações para diferentes funções que fornecem respostas. ele é uma implementação do manipulador de eventos fetch, como mencionado no capítulo "Exibição".
  • workbox-strategies: um conjunto de estratégias de armazenamento em cache em tempo de execução que lida com a resposta a uma solicitação, como armazenar em cache primeiro e ficar obsoleto durante a revalidação. ela é uma implementação das diferentes estratégias mencionadas no capítulo "Exibição".
  • workbox-precaching: é uma implementação de armazenamento em cache de arquivos no manipulador de eventos install do service worker (também conhecido como pré-armazenamento em cache), conforme mencionado no capítulo Armazenamento em cache. Com esse módulo, você pode pré-armazenar em cache um conjunto de arquivos com facilidade e gerenciar com eficiência as atualizações desses recursos. O capítulo "Atualizar" aborda a atualização de recursos.
  • workbox-expiration: é um plug-in usado com as estratégias de armazenamento em cache para remover solicitações armazenadas em cache de acordo com o número de itens armazenados ou o tempo de existência da solicitação armazenada em cache. Ele ajuda a gerenciar seus caches e define limites de tempo e o número de itens em cada cache.
  • workbox-window: um conjunto de módulos destinado a ser executado no contexto da janela, ou seja, nas páginas da Web do PWA. É possível simplificar o processo de registro e atualizações do service worker, além de facilitar a comunicação entre o código em execução no contexto do service worker e o contexto da janela.

Como usar o Workbox

O Workbox oferece diferentes maneiras de integração no seu PWA. Escolha a opção que melhor se adapta à arquitetura do seu app:

  • CLI do Workbox: um utilitário de linha de comando que gera um service worker completo, injeta um manifesto de pré-cache ou copia os arquivos necessários do Workbox.
  • Buildbox de trabalho: um módulo npm que gera um service worker completo, injeta um manifesto de pré-cache e copia os arquivos do Workbox. Ela precisa ser integrada ao seu próprio processo de build.
  • workbox-sw: uma maneira de carregar pacotes de service worker do Workbox de uma CDN que não usa um processo de build.

A CLI do Workbox oferece um assistente que orienta você na criação do service worker. Para executar o assistente, digite o seguinte na linha de comando:

npx workbox-cli wizard

CLI da caixa de trabalho em ação em um terminal

Armazenamento em cache e exibição com a caixa de trabalho

Um uso comum do Workbox é usar os módulos de roteamento e estratégias juntos para armazenar em cache e exibir arquivos.

O módulo workbox-strategies fornece, pronto para uso, as estratégias de armazenamento em cache discutidas nos capítulos Recursos e dados e Exibição.

O módulo workbox-routing ajuda a classificar as solicitações recebidas pelo service worker e associá-las às estratégias ou funções de armazenamento em cache para gerar respostas para essas solicitações.

Após fazer a correspondência das rotas com as estratégias, o Workbox também permite filtrar as respostas que serão adicionadas ao cache com o plug-in workbox-cacheable-response. Com esse plug-in, é possível, por exemplo, armazenar em cache apenas as respostas que retornaram sem erros.

O exemplo de código a seguir usa uma estratégia que prioriza o cache (por meio do módulo CacheFirst) para armazenar em cache e exibir navegações nas páginas.

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';

const pageStrategy = new CacheFirst({
  // Put all cached files in a cache named 'pages'
  cacheName: 'pages',
  plugins: [
    // Only requests that return with a 200 status are cached
    new CacheableResponsePlugin({
      statuses: [200],
    }),
  ],
});

O plug-in permite que você aproveite o armazenamento em cache e o ciclo de vida de resolução de solicitações do Workbox. Aqui, o CacheableResponsePlugin é usado para armazenar apenas solicitações em cache que resultam em um status 200, evitando que solicitações inválidas sejam salvas no cache.

Depois de criar a estratégia, é hora de registrar uma rota para usá-la. O exemplo a seguir chama registerRoute(), transmitindo um objeto Request ao callback. Se request.mode for "navigate", ele usará a estratégia CacheFirst (chamada de pageStrategy) definida no exemplo de código anterior.

// Cache page navigations (HTML) with a Cache First strategy
registerRoute( ({ request }) => request.mode === 'navigate',
  pageStrategy );

Leia a documentação do Workbox para mais exemplos e práticas recomendadas.

Substituto off-line

O módulo workbox-routing também tem um setCatchHandler() exportado, que gerencia quando uma rota gera um erro. Use esse recurso para configurar um substituto off-line e notificar os usuários de que a rota solicitada não está disponível no momento.

Aqui, uma combinação de Workbox e a API Cache Storage fornece um substituto off-line usando uma estratégia somente de cache. Primeiro, durante o ciclo de vida de instalação do service worker, o cache offline-fallbacks é aberto e a matriz de substitutos off-line é adicionada ao cache.

import { setCatchHandler } from 'workbox-routing';

// Warm the cache when the service worker installs
self.addEventListener('install', event => {
  const files = ['/offline.html']; // you can add more resources here
  event.waitUntil(
    self.caches.open('offline-fallbacks')
        .then(cache => cache.addAll(files))
  );
});

Em seguida, em setCatchHandler(), o destino da solicitação que gerou um erro é determinado e o cache offline-fallbacks é aberto. Se o destino for um documento, o conteúdo do substituto off-line será retornado ao usuário. Se não existir ou se o destino não for um documento (como uma imagem ou folha de estilo), uma resposta de erro será retornada. É possível estender esse padrão não apenas para documentos, mas para imagens, vídeos, fontes e qualquer outra coisa que você queira fornecer como substituto off-line.

// Respond with the fallback if a route throws an error
setCatchHandler(async (options) => {
  const destination = options.request.destination;
  const cache = await self.caches.open('offline-fallbacks');
  if (destination === 'document') {
    return (await cache.match('/offline.html')) || Response.error();
  }
  return Response.error();
});

Receitas

Vários padrões de roteamento e armazenamento em cache, como navegações NetworkFirst e substitutos off-line, são comuns o suficiente para serem encapsulados em roteiros reutilizáveis. Confira as receitas de caixa de trabalho, porque elas podem ajudar caso ofereçam uma solução adequada à sua arquitetura. Elas geralmente estão disponíveis como uma linha de código que você precisa adicionar ao código do seu service worker.

Armazenamento em cache e atualização de recursos

Armazenar recursos em cache também envolve atualizá-los. O Workbox ajuda a atualizar seus recursos da maneira que você escolher. Pode ser mantê-los atualizados caso eles mudem no servidor, ou esperar até que você tenha uma nova versão do seu aplicativo. Consulte o capítulo "Atualizar" para saber mais.

Jogar com o Workbox

Você pode testar o Workbox imediatamente usando o seguinte codelab:

Recursos