כשמשיבים לבקשות עם רשומות שנשמרו במטמון, למרות שהן מהירות, המשתמשים עלולים לראות נתונים לא עדכניים.
החבילה 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) => {...}
-
אפשרויות
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
עם האפשרויות שהועברו ומתבצעת קריאה ל-methodnotifyIfUpdated
בכל פעם שמופעל קריאה חוזרת (callback) שלcacheDidUpdate
בפלאגין.הפונקציה
constructor
נראית כך:(options?: BroadcastCacheUpdateOptions) => {...}
-
אפשרויות
BroadcastCacheUpdateOptions אופציונלי
-
החזרות
-
שיטות
responsesAreSame()
workbox-broadcast-update.responsesAreSame(
firstResponse: Response,
secondResponse: Response,
headersToCheck: string[],
)
בהינתן שני ערכי Response's
, משווה כמה ערכי כותרות כדי לראות אם הם זהים או לא.
פרמטרים
-
firstResponse
תשובה
-
secondResponse
תשובה
-
headersToCheck
מחרוזת[]
החזרות
-
boolean