caixa de trabalho-transmissão-atualização

Ao responder a solicitações com entradas em cache, embora seja rápido, isso traz uma desvantagem de que os usuários podem acabar vendo dados desatualizados.

O pacote workbox-broadcast-update oferece uma maneira padrão de notificar clientes de janela que uma resposta armazenada em cache foi atualizada. Ela é mais usada com a estratégia StaleWhileRevalidate.

Sempre que a etapa "revalidar" dessa estratégia recuperar uma resposta da rede diferente da que foi armazenada em cache anteriormente, esse módulo vai enviar uma mensagem (via postMessage()) para todos os clientes do Window no escopo do service worker atual.

Os clientes do Window podem detectar atualizações e tomar as medidas apropriadas, como exibir automaticamente uma mensagem informando ao usuário que as atualizações estão disponíveis.

Como as atualizações são determinadas?

Alguns cabeçalhos dos objetos novos e em cache Response são comparados e, se algum dos cabeçalhos tiver valores diferentes, será considerado uma atualização.

Por padrão, os cabeçalhos Content-Length, ETag e Last-Modified são comparados.

A caixa de trabalho usa valores de cabeçalho em vez de uma comparação byte a byte de corpos de resposta para ser mais eficiente, em particular para respostas potencialmente grandes.

Como usar a atualização de transmissão

A biblioteca é projetada para ser usada com a estratégia de armazenamento em cache StaleWhileRevalidate, já que essa estratégia envolve retornar uma resposta em cache imediatamente, mas também fornece um mecanismo para atualizar o cache de forma assíncrona.

Para transmitir atualizações, basta adicionar um broadcastUpdate.BroadcastUpdatePlugin às suas opções de estratégia.

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';

registerRoute(
  ({url}) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    plugins: [new BroadcastUpdatePlugin()],
  })
);

No seu app da Web, antes que o evento DOMContentLoaded seja disparado, você pode detectar esses eventos da seguinte maneira:

navigator.serviceWorker.addEventListener('message', async event => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.data.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedURL} = event.data.payload;

    // Do something with cacheName and updatedURL.
    // For example, get the cached content and update
    // the content on the page.
    const cache = await caches.open(cacheName);
    const updatedResponse = await cache.match(updatedURL);
    const updatedText = await updatedResponse.text();
  }
});

Formato de mensagem

Quando um listener de eventos message é invocado no seu app da Web, a propriedade event.data tem o seguinte formato:

{
  type: 'CACHE_UPDATED',
  meta: 'workbox-broadcast-update',
  // The two payload values vary depending on the actual update:
  payload: {
    cacheName: 'the-cache-name',
    updatedURL: 'https://example.com/'
  }
}

Personalizar cabeçalhos a serem verificados

Você pode personalizar os cabeçalhos a serem verificados definindo a propriedade headersToCheck.

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';

registerRoute(
  ({url}) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    plugins: [
      new BroadcastUpdatePlugin({
        headersToCheck: ['X-My-Custom-Header'],
      }),
    ],
  })
);

Uso avançado

A maioria dos desenvolvedores usa workbox-broadcast-update como plug-in de uma estratégia específica, conforme mostrado acima, mas é possível usar a lógica subjacente no código do service worker.

import {BroadcastCacheUpdate} from 'workbox-broadcast-update';

const broadcastUpdate = new BroadcastCacheUpdate({
  headersToCheck: ['X-My-Custom-Header'],
});

const cacheName = 'api-cache';
const request = new Request('https://example.com/api');

const cache = await caches.open(cacheName);
const oldResponse = await cache.match(request);
const newResponse = await fetch(request);

broadcastUpdate.notifyIfUpdated({
  cacheName,
  oldResponse,
  newResponse,
  request,
);

Tipos

BroadcastCacheUpdate

Usa a API postMessage() para informar a qualquer janela/guia aberta quando uma resposta armazenada em cache for atualizada.

Para melhorar a eficiência, os corpos de resposta subjacentes não são comparados. Apenas cabeçalhos de resposta específicos são verificados.

Propriedades

  • construtor

    void

    Crie uma instância de BroadcastCacheUpdate com um channelName específico para transmitir mensagens em

    A função constructor tem esta aparência:

    (options?: BroadcastCacheUpdateOptions) => {...}

  • notifyIfUpdated

    void

    Compara duas respostas e envia uma mensagem (via postMessage()) com todos os clientes de janela se as respostas forem diferentes. Nenhuma das respostas pode ser opaca.

    A mensagem postada tem o seguinte formato (em que payload pode ser personalizado por meio da opção generatePayload com que a instância é criada):

    {
      type: 'CACHE_UPDATED',
      meta: 'workbox-broadcast-update',
      payload: {
        cacheName: 'the-cache-name',
        updatedURL: 'https://example.com/'
      }
    }
    

    A função notifyIfUpdated tem esta aparência:

    (options: CacheDidUpdateCallbackParam) => {...}

    • retorna

      Promise<void>

      Resolve quando a atualização é enviada.

BroadcastCacheUpdateOptions

Propriedades

BroadcastUpdatePlugin

Este plug-in vai transmitir automaticamente uma mensagem sempre que uma resposta em cache for atualizada.

Propriedades

  • construtor

    void

    Crie uma instância workbox-broadcast-update.BroadcastUpdate com as opções transmitidas e chame o método notifyIfUpdated sempre que o callback cacheDidUpdate do plug-in for invocado.

    A função constructor tem esta aparência:

    (options?: BroadcastCacheUpdateOptions) => {...}

Métodos

responsesAreSame()

workbox-broadcast-update.responsesAreSame(
  firstResponse: Response,
  secondResponse: Response,
  headersToCheck: string[],
)

Dado dois Response's, compara vários valores de cabeçalho para ver se eles são iguais ou não.

Parâmetros

  • firstResponse

    Resposta

  • secondResponse

    Resposta

  • headersToCheck

    string[]

Retorna

  • boolean