เมื่อตอบกลับคำขอด้วยรายการที่แคชไว้ในขณะที่ดำเนินการได้เร็ว ก็จะมีข้อดีข้อเสียที่ผู้ใช้อาจพบข้อมูลที่ไม่อัปเดต
แพ็กเกจ workbox-broadcast-update
เป็นวิธีมาตรฐานในการแจ้งเตือนไคลเอ็นต์หน้าต่างว่ามีการอัปเดตการตอบสนองที่แคชไว้ ซึ่งโดยทั่วไปจะใช้ร่วมกับกลยุทธ์ StaleWhileRevalidate
เมื่อใดก็ตามที่ขั้นตอน "ตรวจสอบอีกครั้ง" ของกลยุทธ์นั้นดึงการตอบสนองจากเครือข่ายซึ่งแตกต่างจากเครือข่ายที่เคยแคชไว้ โมดูลนี้จะส่งข้อความ (ผ่าน postMessage()
) ไปยัง Window Client ทั้งหมดภายในขอบเขตของ Service Worker ปัจจุบัน
โปรแกรมไคลเอ็นต์หน้าต่างจะคอยฟังการอัปเดตและดำเนินการตามความเหมาะสม เช่น การแสดงข้อความแจ้งให้ผู้ใช้ทราบว่ามีการอัปเดตโดยอัตโนมัติ
มีวิธีการกำหนดการอัปเดตอย่างไร
ระบบจะเปรียบเทียบส่วนหัวบางรายการของออบเจ็กต์ 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();
}
});
รูปแบบข้อความ
เมื่อมีการเรียกใช้ Listener เหตุการณ์ 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
สร้างอินสแตนซ์ BroadcastCacheUpdate ที่มี
channelName
ที่ระบุเพื่อประกาศข้อความฟังก์ชัน
constructor
มีลักษณะดังนี้(options?: BroadcastCacheUpdateOptions) => {...}
-
ตัวเลือก
BroadcastCacheUpdateOptions ไม่บังคับ
-
returns
-
-
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) => {...}
-
ตัวเลือก
-
returns
Promise<void>
แก้ไขเมื่อมีการส่งการอัปเดต
-
BroadcastCacheUpdateOptions
พร็อพเพอร์ตี้
-
headersToCheck
string[] ไม่บังคับ
-
notifyAllClients
บูลีน ไม่บังคับ
-
generatePayload
เป็นโมฆะ ไม่บังคับ
ฟังก์ชัน
generatePayload
มีลักษณะดังนี้(options: CacheDidUpdateCallbackParam) => {...}
-
ตัวเลือก
-
returns
บันทึก<stringany>
-
BroadcastUpdatePlugin
ปลั๊กอินนี้จะเผยแพร่ข้อความโดยอัตโนมัติทุกครั้งที่มีการอัปเดตการตอบสนองที่แคชไว้
พร็อพเพอร์ตี้
-
เครื่องมือสร้าง
void
สร้างอินสแตนซ์
workbox-broadcast-update.BroadcastUpdate
ด้วยตัวเลือกที่ส่งและเรียกใช้เมธอดnotifyIfUpdated
เมื่อใดก็ตามที่มีการเรียกกลับcacheDidUpdate
ของปลั๊กอินฟังก์ชัน
constructor
มีลักษณะดังนี้(options?: BroadcastCacheUpdateOptions) => {...}
-
ตัวเลือก
BroadcastCacheUpdateOptions ไม่บังคับ
-
returns
-
วิธีการ
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
)
เมื่อใช้ Response's
2 ค่า ให้เปรียบเทียบค่าส่วนหัวหลายๆ ค่าเพื่อดูว่าเหมือนกันหรือไม่
พารามิเตอร์
-
firstResponse
คำตอบ
-
secondResponse
คำตอบ
-
headersToCheck
สตริง[]
การคืนสินค้า
-
boolean