Cuando respondes solicitudes con entradas almacenadas en caché, aunque es rápido, se produce la desventaja de que los usuarios podrían terminar viendo datos inactivos.
El paquete workbox-broadcast-update
proporciona una forma estándar de notificar a los clientes de Windows que se actualizó una respuesta almacenada en caché. Por lo general, se usa junto con la estrategia StaleWhileRevalidate
.
Cuando el paso "revalidar" de esa estrategia recupera una respuesta de la red que difiere de la que se almacenó en caché antes, este módulo enviará un mensaje (a través de postMessage()
) a todos los clientes de Windows dentro del alcance del service worker actual.
Los clientes de Windows pueden detectar actualizaciones y tomar las medidas adecuadas, como mostrar automáticamente un mensaje al usuario para informarle que hay actualizaciones disponibles.
¿Cómo se determinan las actualizaciones?
Se comparan algunos encabezados de los objetos Response
nuevos y almacenados en caché, y si alguno de ellos tiene valores diferentes, se considera una actualización.
De forma predeterminada, se comparan los encabezados Content-Length
, ETag
y Last-Modified
.
Workbox usa valores de encabezado en lugar de una comparación byte por byte de los cuerpos de la respuesta a fin de ser más eficiente, en particular para respuestas potencialmente grandes
Cómo usar la actualización de transmisión
La biblioteca está diseñada para usarse junto con la estrategia de almacenamiento en caché StaleWhileRevalidate
, ya que esa estrategia implica mostrar una respuesta almacenada en caché de inmediato, pero también proporciona un mecanismo para actualizar la caché de forma asíncrona.
Para transmitir actualizaciones, solo debes agregar un broadcastUpdate.BroadcastUpdatePlugin
a tus opciones de estrategia.
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()],
})
);
En tu aplicación web, antes de que se active el evento DOMContentLoaded
, puedes escuchar estos eventos de la siguiente manera:
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 del mensaje
Cuando se invoca un objeto de escucha de eventos message
en tu app web, la propiedad
event.data
tendrá el siguiente 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 los encabezados que se deben verificar
Puedes configurar la propiedad headersToCheck
para personalizar los encabezados que se deben verificar.
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 avanzado
Si bien la mayoría de los desarrolladores usarán workbox-broadcast-update
como complemento de una estrategia en particular, como se muestra arriba, es posible usar la lógica subyacente en el código del 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 la API de postMessage()
para informar cualquier ventana o pestaña abierta cuando se actualiza una respuesta almacenada en caché.
Por cuestiones de eficiencia, los cuerpos de la respuesta subyacentes no se comparan; solo se verifican los encabezados de respuesta específicos.
Propiedades
-
constructor
void
Crea una instancia de BroadcastCacheUpdate con un
channelName
específico para transmitir mensajes enLa función
constructor
se ve de la siguiente manera:(options?: BroadcastCacheUpdateOptions) => {...}
-
Opciones
BroadcastCacheUpdateOptions opcional
-
resultados
-
-
notifyIfUpdated
void
Compara dos respuestas y envía un mensaje (a través de
postMessage()
) a todos los clientes de ventana si las respuestas son diferentes. Ninguna de las respuestas puede ser opaca.El mensaje que se publica tiene el siguiente formato (en el que
payload
se puede personalizar mediante la opcióngeneratePayload
con la que se crea la instancia):{ type: 'CACHE_UPDATED', meta: 'workbox-broadcast-update', payload: { cacheName: 'the-cache-name', updatedURL: 'https://example.com/' } }
La función
notifyIfUpdated
se ve de la siguiente manera:(options: CacheDidUpdateCallbackParam) => {...}
-
Opciones
-
resultados
Promise<void>
Se resuelve una vez que se envía la actualización.
-
BroadcastCacheUpdateOptions
Propiedades
-
headersToCheck
string[] opcional
-
notifyAllClients
booleano opcional
-
generatePayload
void opcional
La función
generatePayload
se ve de la siguiente manera:(options: CacheDidUpdateCallbackParam) => {...}
-
Opciones
-
resultados
Grabar<stringany>
-
BroadcastUpdatePlugin
Este complemento transmitirá automáticamente un mensaje cada vez que se actualice una respuesta almacenada en caché.
Propiedades
-
constructor
void
Crea una instancia de
workbox-broadcast-update.BroadcastUpdate
con las opciones pasadas y llama a su métodonotifyIfUpdated
cada vez que se invoque la devolución de llamadacacheDidUpdate
del complemento.La función
constructor
se ve de la siguiente manera:(options?: BroadcastCacheUpdateOptions) => {...}
-
Opciones
BroadcastCacheUpdateOptions opcional
-
resultados
-
Métodos
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
)
Dados dos Response's
, compara varios valores de encabezado para ver si son iguales o no.
Parámetros
-
firstResponse
Respuesta
-
secondResponse
Respuesta
-
headersToCheck
string[]
Devuelve
-
boolean