使用缓存条目响应请求时,虽然速度快, 但用户可能会看到过时的数据
workbox-broadcast-update 软件包提供了一种标准方式,用于通知 Window 客户端缓存的响应已更新。此策略最常与 StaleWhileRevalidate 策略搭配使用。
每当该策略的“重新验证”步骤从网络检索的响应与之前缓存的内容不同时,此模块都会向当前服务工作器范围内的所有窗口客户端发送消息(通过 postMessage())。
窗口客户端可以监听更新并执行适当的操作,例如自动向用户显示消息,告知他们有更新可用。
系统如何确定更新?
系统会比较缓存的 Response 对象和新 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()],
  })
);
在 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
属性
- 
    headersToCheck
string[] 选填
 - 
    notifyAllClients
布尔值(可选)
 - 
    generatePayload
void 可选
generatePayload函数如下所示:(options: CacheDidUpdateCallbackParam) => {...}
- 
            返回
记录<stringany>
 
 - 
            
 
BroadcastUpdatePlugin
每当缓存的响应更新时,此插件都会自动广播一条消息。
属性
- 
    构造函数
void
使用传递的选项构建
workbox-broadcast-update.BroadcastUpdate实例,并在每次调用插件的cacheDidUpdate回调时调用其notifyIfUpdated方法。constructor函数如下所示:(options?: BroadcastCacheUpdateOptions) => {...}
- 
    选项
BroadcastCacheUpdateOptions optional
 
 - 
    
 
方法
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
): boolean
给定两个 Response's,比较多个标头值,看看它们是否
不同。
参数
- 
    firstResponse
响应
 - 
    secondResponse
响应
 - 
    headersToCheck
字符串[]
 
返回
- 
            
布尔值