עדכון תיבת עבודה-שידור

כשמשיבים לבקשות עם רשומות שנשמרו במטמון, למרות שהן מהירות, המשתמשים עלולים לראות נתונים לא עדכניים.

החבילה workbox-broadcast-update מספקת דרך סטנדרטית להודיע ללקוחות חלון על עדכון תגובה שנשמרה במטמון. בדרך כלל משתמשים באפשרות הזאת יחד עם האסטרטגיה StaleWhileRevalidate.

כשהשלב "אימות מחדש" בשיטה הזו מאחזר תגובה מהרשת ששונה מזו שנשמרה במטמון בעבר, המודול הזה שולח הודעה (דרך postMessage()) לכל לקוחות החלון שבהיקף של Service Worker הנוכחי.

לקוחות של חלונות יכולים להאזין לעדכונים ולנקוט פעולה מתאימה, כמו הצגה אוטומטית של הודעה למשתמשים שיש עדכונים זמינים.

איך נקבעים עדכונים?

מתבצעת השוואה בין הכותרות מסוימות של האובייקטים השמורים במטמון והאובייקטים החדשים Response, ואם יש מהכותרות ערכים שונים, הדבר נחשב כעדכון.

כברירת מחדל, מתבצעת השוואה בין הכותרות Content-Length, ETag ו-Last-Modified.

כדי לשפר את היעילות של גופי תגובה, במיוחד בתגובות שעשויות להיות גדולות, נעשה שימוש בערכי כותרות במקום בהשוואה של בייטים לבייטים

שימוש ב'עדכון שידור'

אפשר להשתמש בספרייה יחד עם אסטרטגיית השמירה במטמון של 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

נעשה שימוש ב-API postMessage() כדי להודיע לכל החלונות או הכרטיסיות הפתוחים על עדכון תגובה שנשמרה במטמון.

מטעמי יעילות, לא מתבצעת השוואה בין גופי התגובה הבסיסיים. נבדקות רק כותרות של תגובות ספציפיות.

תכונות

  • Constructor

    void

    יצירת מופע של BroadcastCacheUpdate עם channelName ספציפי לשידור הודעות

    הפונקציה 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)=> {...}

    • החזרות

      Promise<void>

      הבעיה תיפתר לאחר שליחת העדכון.

BroadcastCacheUpdateOptions

תכונות

  • headersToCheck

    string[] אופציונלי

  • notifyAllClients

    בוליאני אופציונלי

  • generatePayload

    ביטול אופציונלי

    הפונקציה generatePayload נראית כך:

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

    • החזרות

      הקלטה<stringany>

BroadcastUpdatePlugin

הפלאגין הזה ישדר הודעה באופן אוטומטי בכל פעם שתגובה שנשמרה במטמון תתעדכן.

תכונות

  • Constructor

    void

    יוצרים מכונה workbox-broadcast-update.BroadcastUpdate עם האפשרויות שהועברו ומתבצעת קריאה ל-method notifyIfUpdated בכל פעם שמופעל קריאה חוזרת (callback) של cacheDidUpdate בפלאגין.

    הפונקציה constructor נראית כך:

    (options?: BroadcastCacheUpdateOptions)=> {...}

שיטות

responsesAreSame()

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

בהינתן שני ערכי Response's, משווה כמה ערכי כותרות כדי לראות אם הם זהים או לא.

פרמטרים

  • firstResponse

    תשובה

  • secondResponse

    תשובה

  • headersToCheck

    מחרוזת[]

החזרות

  • boolean