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 emA função
constructor
tem esta aparência:(options?: BroadcastCacheUpdateOptions) => {...}
-
opções
BroadcastCacheUpdateOptions opcional
-
retorna
-
-
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çãogeneratePayload
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) => {...}
-
opções
-
retorna
Promise<void>
Resolve quando a atualização é enviada.
-
BroadcastCacheUpdateOptions
Propriedades
-
headersToCheck
string[] opcional
-
notifyAllClients
booleano opcional
-
generatePayload
void optional
A função
generatePayload
tem esta aparência:(options: CacheDidUpdateCallbackParam) => {...}
-
opções
-
retorna
Gravar<stringany>
-
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étodonotifyIfUpdated
sempre que o callbackcacheDidUpdate
do plug-in for invocado.A função
constructor
tem esta aparência:(options?: BroadcastCacheUpdateOptions) => {...}
-
opções
BroadcastCacheUpdateOptions opcional
-
retorna
-
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