在快速回應含有快取項目的要求時,偶爾會權衡使用者看到過時的資料。
workbox-broadcast-update
套件提供一種標準方式,可通知視窗用戶端快取回應已更新。最常與 StaleWhileRevalidate
策略搭配使用。
只要該策略的「重新驗證」步驟從網路擷取與先前快取內容不同的回應,這個模組就會透過 postMessage()
傳送訊息至當前 Service Worker 範圍內的所有 Window 用戶端。
Window 用戶端可以監聽更新並採取適當行動,例如自動向使用者顯示訊息,讓使用者知道有可用的更新。
如何決定更新?
系統會比較快取和新 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
做為特定策略的外掛程式,但您也可以在 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) => {...}
-
returns
-
-
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
屬性
-
headersToCheck
string[] 選填
-
notifyAllClients
布林值 (選用)
-
generatePayload
void optional
generatePayload
函式如下所示:(options: CacheDidUpdateCallbackParam) => {...}
-
returns
紀錄<stringany>
-
BroadcastUpdatePlugin
每當快取回應更新時,這個外掛程式就會自動廣播訊息。
屬性
-
建構函式
void
使用傳遞的選項建構
workbox-broadcast-update.BroadcastUpdate
例項,並在每次叫用外掛程式的cacheDidUpdate
回呼時呼叫其notifyIfUpdated
方法。constructor
函式如下所示:(options?: BroadcastCacheUpdateOptions) => {...}
-
returns
-
方法
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
)
在兩個 Response's
下,比較多個標頭值,確認這些值是否相同。
參數
-
firstResponse
回應
-
secondResponse
回應
-
headersToCheck
string[]
傳回
-
boolean