Workbox-broadcast-update

在快速回應含有快取項目的要求時,偶爾會權衡使用者看到過時的資料。

workbox-broadcast-update 套件提供一種標準方式,可通知視窗用戶端快取回應已更新。最常與 StaleWhileRevalidate 策略搭配使用。

只要該策略的「重新驗證」步驟從網路擷取與先前快取內容不同的回應,這個模組就會透過 postMessage() 傳送訊息至當前 Service Worker 範圍內的所有 Window 用戶端。

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

    比較兩個回應,並在回應不同時透過 postMessage() 向所有視窗用戶端傳送訊息。這兩個回應都不透明

    張貼的訊息採用下列格式 (其中 payload 可透過建立執行個體時使用的 generatePayload 選項自訂):

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

    notifyIfUpdated 函式如下所示:

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

    • returns

      Promise<void>

      傳送更新後解決。

BroadcastCacheUpdateOptions

屬性

BroadcastUpdatePlugin

每當快取回應更新時,這個外掛程式就會自動廣播訊息。

屬性

方法

responsesAreSame()

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

在兩個 Response's 下,比較多個標頭值,確認這些值是否相同。

參數

  • firstResponse

    回應

  • secondResponse

    回應

  • headersToCheck

    string[]

傳回

  • boolean