При ответе на запросы с кешированными записями, несмотря на скорость, пользователи могут в конечном итоге увидеть устаревшие данные.
Пакет workbox-broadcast-update
предоставляет стандартный способ уведомления клиентов Windows об обновлении кэшированного ответа. Чаще всего это используется вместе со стратегией StaleWhileRevalidate
.
Всякий раз, когда шаг «повторной проверки» этой стратегии получает ответ из сети, который отличается от того, что было ранее кэшировано, этот модуль отправляет сообщение (через postMessage()
) всем клиентам Window в пределах области действия текущего сервисного работника.
Клиенты Windows могут прослушивать обновления и предпринимать соответствующие действия, например автоматически отображать пользователю сообщение о доступности обновлений.
Как определяются обновления?
Определенные заголовки кэшированных и новых объектов Response
сравниваются, и если какой-либо из заголовков имеет разные значения, это считается обновлением.
По умолчанию сравниваются заголовки Content-Length
, ETag
и Last-Modified
.
Workbox использует значения заголовков вместо побайтового сравнения тел ответов, чтобы быть более эффективным, особенно для потенциально больших ответов.
Использование широковещательного обновления
Библиотека предназначена для использования вместе со стратегией кэширования StaleWhileRevalidate
, поскольку эта стратегия предполагает немедленный возврат кэшированного ответа, а также предоставляет механизм асинхронного обновления кэша.
Для трансляции обновлений вам просто нужно добавить broadcastUpdate.BroadcastUpdatePlugin
в параметры вашей стратегии.
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()],
})
);
В вашем веб-приложении до того, как сработает событие DOMContentLoaded
, вы можете прослушивать эти события следующим образом:
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();
}
});
Формат сообщения
Когда в вашем веб-приложении вызывается прослушиватель событий message
, свойство event.data
будет иметь следующий формат:
{
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/'
}
}
Настройте заголовки для проверки
Вы можете настроить заголовки для проверки, установив свойство 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'],
}),
],
})
);
Расширенное использование
Хотя большинство разработчиков будут использовать workbox-broadcast-update
в качестве плагина определенной стратегии, как показано выше, можно использовать базовую логику в коде сервис-воркера.
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,
);
Типы
BroadcastCacheUpdate
Использует API postMessage()
для информирования всех открытых окон/вкладок об обновлении кэшированного ответа.
В целях эффективности базовые тела ответа не сравниваются; проверяются только определенные заголовки ответов.
Характеристики
- конструктор
пустота
Создайте экземпляр BroadcastCacheUpdate с определенным
channelName
для трансляции сообщений.Функция
constructor
выглядит так:(options?: BroadcastCacheUpdateOptions) => {...}
- параметры
BroadcastCacheUpdateOptions необязательно.
- возвращает
- уведомитьЕслиОбновлено
пустота
Сравнивает два ответа и отправляет сообщение (через
postMessage()
) всем оконным клиентам, если ответы различаются. Ни один из ответов не может быть непрозрачным .Опубликованное сообщение имеет следующий формат (где
payload
можно настроить с помощьюgeneratePayload
, с помощью которого создается экземпляр):{ type: 'CACHE_UPDATED', meta: 'workbox-broadcast-update', payload: { cacheName: 'the-cache-name', updatedURL: 'https://example.com/' } }
Функция
notifyIfUpdated
выглядит так:(options: CacheDidUpdateCallbackParam) => {...}
- параметры
- возвращает
Обещание<void>
Решается после отправки обновления.
BroadcastCacheUpdateOptions
Характеристики
- заголовкиToCheck
строка[] необязательно
- уведомитьВсеклиенты
логическое значение необязательно
- генерировать полезную нагрузку
аннулировать необязательно
Функция
generatePayload
выглядит так:(options: CacheDidUpdateCallbackParam) => {...}
- параметры
- возвращает
Запись<строка>
BroadcastUpdatePlugin
Этот плагин автоматически передает сообщение при каждом обновлении кэшированного ответа.
Характеристики
- конструктор
пустота
Создайте экземпляр
workbox-broadcast-update.BroadcastUpdate
с переданными параметрами и вызывайте его методnotifyIfUpdated
всякий раз, когда вызывается обратный вызовcacheDidUpdate
плагина.Функция
constructor
выглядит так:(options?: BroadcastCacheUpdateOptions) => {...}
- параметры
BroadcastCacheUpdateOptions необязательно.
- возвращает
Методы
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
)
Учитывая два Response's
, сравнивает несколько значений заголовков, чтобы увидеть, одинаковы они или нет.
Параметры
- первый ответ
Ответ
- второй ответ
Ответ
- заголовкиToCheck
нить[]
Возврат
логическое значение