#workboxbroadcast-update

キャッシュに保存されたエントリを使用してリクエストに応答する場合、高速ですが、ユーザーに古いデータが表示されるというトレードオフが伴います。

workbox-broadcast-update パッケージは、キャッシュに保存されたレスポンスが更新されたことをウィンドウ クライアントに通知する標準的な方法を提供します。これは、StaleWhileRevalidate 戦略と併用するのが一般的です。

その戦略の「再検証」ステップで、以前にキャッシュに保存されたものとは異なるレスポンスをネットワークから取得するたび、このモジュールは現在の Service Worker のスコープ内にあるすべてのウィンドウ クライアントに(postMessage() を介して)メッセージを送信します。

Window クライアントは、更新をリッスンし、更新が利用可能であることを知らせるメッセージを自動的に表示するなど、適切なアクションを実行できます。

更新の決定方法

キャッシュされたオブジェクトと新しい Response オブジェクトの特定のヘッダーが比較され、いずれかのヘッダーの値が異なる場合は更新とみなされます。

デフォルトでは、Content-LengthETagLast-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 を使用しますが、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,
);

BroadcastCacheUpdate

postMessage() API を使用して、キャッシュに保存されたレスポンスが更新されたことを、開いているウィンドウまたはタブに通知します。

効率上、基になるレスポンスの本文は比較されません。特定のレスポンス ヘッダーのみがチェックされます。

プロパティ

  • コンストラクタ

    void

    特定の channelName で BroadcastCacheUpdate インスタンスを作成し、メッセージをブロードキャストします。

    constructor 関数は次のようになります。

    (options?: BroadcastCacheUpdateOptions)=> {...}

  • notifyIfUpdated

    void

    2 つのレスポンスを比較し、レスポンスが異なる場合は、すべてのウィンドウ クライアントにメッセージを(postMessage() を介して)送信します。どちらのレスポンスも不透明にできません。

    投稿されるメッセージの形式は次のとおりです(payload は、インスタンスの作成に使用する generatePayload オプションを使用してカスタマイズできます)。

    {
      type: 'CACHE_UPDATED',
      meta: 'workbox-broadcast-update',
      payload: {
        cacheName: 'the-cache-name',
        updatedURL: 'https://example.com/'
      }
    }
    

    notifyIfUpdated 関数は次のようになります。

    (options: CacheDidUpdateCallbackParam)=> {...}

    • 戻り値

      Promise<void>

      アップデートが送信されると解決します。

BroadcastCacheUpdateOptions

プロパティ

  • headersToCheck

    string[] 省略可

  • notifyAllClients

    ブール値(省略可)

  • generatePayload

    void 省略可

    generatePayload 関数は次のようになります。

    (options: CacheDidUpdateCallbackParam)=> {...}

    • 戻り値

      レコード<stringany>

BroadcastUpdatePlugin

このプラグインは、キャッシュに保存されたレスポンスが更新されるたびに、メッセージを自動的にブロードキャストします。

プロパティ

  • コンストラクタ

    void

    渡されたオプションで workbox-broadcast-update.BroadcastUpdate インスタンスを作成し、プラグインの cacheDidUpdate コールバックが呼び出されるたびに、その notifyIfUpdated メソッドを呼び出します。

    constructor 関数は次のようになります。

    (options?: BroadcastCacheUpdateOptions)=> {...}

Methods

responsesAreSame()

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

2 つの Response's が与えられた場合、複数のヘッダー値を比較して、それらが同じかどうかを確認します。

パラメータ

  • firstResponse

    レスポンス

  • secondResponse

    レスポンス

  • headersToCheck

    string[]

戻り値

  • boolean