обновление рабочего ящика-трансляции

При ответе на запросы с кешированными записями, несмотря на скорость, пользователи могут в конечном итоге увидеть устаревшие данные.

Пакет 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) => {...}

  • уведомитьЕслиОбновлено

    пустота

    Сравнивает два ответа и отправляет сообщение (через 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) => {...}

Методы

responsesAreSame()

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

Учитывая два Response's , сравнивает несколько значений заголовков, чтобы увидеть, одинаковы они или нет.

Параметры

  • первый ответ

    Ответ

  • второй ответ

    Ответ

  • заголовкиToCheck

    нить[]

Возврат

  • логическое значение