Workbox

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

Ele pode ajudar a corresponder estratégias de armazenamento em cache a caminhos (ou padrões de roteamento), trabalhar com streams e usar recursos como sincronização em segundo plano com substitutos adequados.

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

54%

Sites móveis com service workers usam a biblioteca Workbox

Módulos da caixa de trabalho

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

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

  • Em um contexto de service worker: importe os módulos necessários e use-os do seu arquivo de service worker, por exemplo, para ajudar a gerenciar o armazenamento em cache e disponibilizar arquivos com diferentes estratégias.
  • No contexto principal de window: ajudar a registrar um service worker e se comunicar com ele
  • Como parte de um sistema de compilação: por exemplo, webpack, para fins como 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, esse módulo encaminha essas solicitações para diferentes funções que fornecem respostas. É uma implementação do manipulador de eventos fetch, conforme mencionado no capítulo "Exibição".
  • estratégias de caixa de trabalho: um conjunto de estratégias de armazenamento em cache no ambiente de execução que lida com a resposta a uma solicitação, como armazenar em cache primeiro e ficar desatualizado durante a revalidação. É 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 este módulo, você pode pré-armazenar em cache um conjunto de arquivos e gerenciar com eficiência as atualizações desses recursos. Confira mais detalhes sobre a atualização de recursos no capítulo "Atualizar".
  • workbox-expiration: é um plug-in usado com as estratégias de armazenamento em cache para remover solicitações armazenadas em cache com base no número de itens ou no tempo da solicitação em cache. Ele ajuda a gerenciar seus caches e define limites de tempo e de número de itens em cada cache.
  • workbox-window: um conjunto de módulos destinados a serem executados no contexto da janela, ou seja, dentro das páginas da Web dos PWAs. É possível simplificar o processo de registro e atualizações do service worker e facilitar a comunicação entre o código em execução no contexto do service worker e o contexto da janela.

Usar o Workbox

O Workbox oferece diferentes maneiras de integração com seu PWA. Escolha a opção mais adequada à 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 arquivos necessários do Workbox.
  • Workbox Build: um módulo npm que gera um service worker completo, injeta um manifesto de pré-cache e copia os arquivos do Workbox. Isso deve ser integrado ao seu próprio processo de compilação.
  • workbox-sw: uma maneira de carregar pacotes de service workers do Workbox de uma CDN que não usa um processo de compilação.

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 do Workbox em ação em um terminal

Como armazenar em cache e exibir com o Workbox

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

O módulo estratégias de caixa de trabalho fornece, prontas 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 para o service worker e faz a correspondência delas com as estratégias ou funções de armazenamento em cache para receber respostas para essas solicitações.

Após a correspondência de rotas com as estratégias, o Workbox também permite filtrar quais respostas serão adicionadas ao cache com o plug-in workbox-cacheable-response. Com esse plug-in, você pode, por exemplo, armazenar em cache somente 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 acessar o armazenamento em cache do Workbox e o ciclo de vida da resolução de solicitações. Aqui, o CacheableResponsePlugin é usado para armazenar em cache apenas solicitações 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 de solicitação 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 oferece tratamento caso uma rota gere um erro. É possível usar 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 do Workbox com a API Cache Storage oferece um fallback 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 isso 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 também 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();
});

Recipes

Vários padrões de roteamento e armazenamento em cache, como as navegações NetworkFirst e os substitutos off-line, são comuns o suficiente para serem encapsulados em roteiros reutilizáveis. Marque os workbox-recipes porque eles podem ajudar se fornecerem uma solução adequada para sua arquitetura. Elas geralmente estão disponíveis como uma linha de código que você precisa adicionar ao código do service worker.

Armazenamento em cache e atualização de recursos

O armazenamento em cache de recursos também envolve a atualização deles. O Workbox ajuda a atualizar seus recursos da maneira que você decidir que é melhor. Isso pode ser mantê-los atualizados se eles mudarem no servidor ou esperar até que você tenha uma nova versão do app. Saiba mais sobre atualizações no capítulo Atualizar.

Jogar com o Workbox

Você pode começar a usar o Workbox imediatamente usando este codelab:

Recursos