workbox-broadcast-update

เมื่อตอบกลับคำขอด้วยรายการที่แคชไว้ในขณะที่ดำเนินการได้เร็ว ก็จะมีข้อดีข้อเสียที่ผู้ใช้อาจพบข้อมูลที่ไม่อัปเดต

แพ็กเกจ 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)=> {...}

  • 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)=> {...}

วิธีการ

responsesAreSame()

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

เมื่อใช้ Response's 2 ค่า ให้เปรียบเทียบค่าส่วนหัวหลายๆ ค่าเพื่อดูว่าเหมือนกันหรือไม่

พารามิเตอร์

  • firstResponse

    คำตอบ

  • secondResponse

    คำตอบ

  • headersToCheck

    สตริง[]

การคืนสินค้า

  • boolean