工作区广播更新

使用缓存条目响应请求时,虽然速度快, 但用户可能会看到过时的数据

workbox-broadcast-update 软件包提供了一种标准方式,用于通知 Window 客户端缓存的响应已更新。此策略最常与 StaleWhileRevalidate 策略搭配使用。

每当该策略的“重新验证”步骤从网络检索的响应与之前缓存的内容不同时,此模块都会向当前服务工作器范围内的所有窗口客户端发送消息(通过 postMessage())。

窗口客户端可以监听更新并执行适当的操作,例如自动向用户显示消息,告知他们有更新可用。

系统如何确定更新?

系统会比较缓存的 Response 对象和新 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()],
  })
);

在 Web 应用中,您可以在 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();
  }
});

消息格式

在 Web 应用中调用 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

    比较两个响应 并根据情况向所有窗口客户端发送一条消息(通过 postMessage()) 。任何一个响应都不能是 opaque

    发布的消息采用以下格式(其中 payload 可以通过实例创建时使用的 generatePayload 选项进行自定义):

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

    notifyIfUpdated 函数如下所示:

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

    • 返回

      承诺<void>

      发送更新后解析。

BroadcastCacheUpdateOptions

属性

BroadcastUpdatePlugin

每当缓存的响应更新时,此插件都会自动广播一条消息。

属性

方法

responsesAreSame()

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

给定两个 Response's,比较多个标头值,看看它们是否 不同。

参数

  • firstResponse

    响应

  • secondResponse

    响应

  • headersToCheck

    字符串[]

返回

  • 布尔值