При ответе на запросы с кешированными записями, несмотря на скорость, пользователи могут в конечном итоге увидеть устаревшие данные.
Пакет 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
нить[]
Возврат
логическое значение