ב-2015 השקנו את התכונה 'סנכרון ברקע', שמאפשרת Service Worker ידחה את העבודה עד שלמשתמש תהיה קישוריות. כלומר, המשתמש יכול להקליד ללחוץ על 'שליחה', ולצאת מהאתר בידיעה שההודעה תישלח עכשיו, או כאשר הם יש קישוריות.
זו תכונה שימושית, אבל כדי שה-Service Worker יהיה בחיים במהלך אחזור. אין בעיה בקטעים קצרים של עבודה, כמו שליחת הודעה, אבל אם המשימה נמשכת יותר מדי זמן הדפדפן ימות את Service Worker, אחרת הדבר מהווה סיכון לפרטיות המשתמש סוללה.
אז מה קורה אם אתם צריכים להוריד משהו שעשוי לקחת זמן רב, כמו סרט, פודקאסטים או שלבים במשחק. זו המטרה של אחזור ברקע.
אחזור ברקע זמין כברירת מחדל החל מגרסה 74 של Chrome.
הנה הדגמה קצרה בת שתי דקות שמראה את המצב המסורתי לעומת השימוש באחזור ברקע:
כדאי לנסות את ההדגמה בעצמכם ולעיין בקוד.
איך זה עובד
אחזור ברקע פועל כך:
- אומרים לדפדפן לבצע קבוצה של שליפות ברקע.
- הדפדפן מאחזר את הדברים האלה ומציג למשתמש את ההתקדמות.
- אחרי שהשליפה הושלמה או נכשלה, הדפדפן יפתח את Service Worker ויפעיל אירוע. כדי לספר לכם מה קרה. זה המקום שבו אתם מחליטים מה לעשות עם התשובות, אם בכלל.
אם המשתמש סוגר את הדפים באתר אחרי שלב 1, אין בעיה, ההורדה תמשיך. כי האחזור גלוי מאוד וניתן לבטל אותו, אין בעיית פרטיות לשמירה על מידע ארוך מדי משימת סנכרון ברקע. מכיוון שה-Service worker לא פועל כל הזמן, אין מה לדאוג שהוא עלול לנצל לרעה את המערכת, למשל כריית ביטקוין ברקע.
בפלטפורמות מסוימות (כמו Android) הדפדפן יכול להיסגר אחרי שלב 1, באופן הבא: הדפדפן יכול להעביר את האחזור למערכת ההפעלה.
אם המשתמש מתחיל את ההורדה במצב אופליין, או עובר למצב אופליין במהלך ההורדה, תתבצע הפעלה ברקע האחזור יושהה ויתחדש מאוחר יותר.
ממשק API
זיהוי תכונה
כמו בכל תכונה חדשה, צריך לבדוק אם הדפדפן תומך בה. לאחזור ברקע, פשוטים כמו:
if ('BackgroundFetchManager' in self) {
// This browser supports Background Fetch!
}
התחלת אחזור ברקע
ה-API הראשי מנותק מרישום של service worker, אז ודאו קודם שרשמתם קובץ שירות (service worker). לאחר מכן:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
title: 'Episode 5: Interesting things.',
icons: [{
sizes: '300x300',
src: '/ep-5-icon.png',
type: 'image/png',
}],
downloadTotal: 60 * 1024 * 1024,
});
});
הפונקציה backgroundFetch.fetch
מקבלת שלושה ארגומנטים:
פרמטרים | |
---|---|
id |
string מזהה באופן ייחודי את האחזור הזה ברקע. האפליקציה |
requests |
Array<Request|string>
דברים שכדאי לאחזר. מחרוזות ייחשבו ככתובות URL, Request דרך new Request(theString) .
אפשר לאחזר דברים ממקורות אחרים כל עוד המשאבים מאפשרים זאת דרך CORS הערה: בשלב זה, Chrome לא תומך בבקשות שעלולות נדרשת קדם-הפעלה של CORS. |
options |
אובייקט שעשוי לכלול: |
options.title |
string כותרת שתוצג בדפדפן לצד ההתקדמות. |
options.icons |
Array<IconDefinition> מערך אובייקטים עם 'src', 'size' ו-'type'. |
options.downloadTotal |
number הגודל הכולל של גופי התגובה (לאחר הסרת ה-gzip). ההגדרה הזו אופציונלית, אבל מומלץ מאוד לספק אותה. הוא משמש לומר למשתמש מה גודל ההורדה ולספק מידע על התקדמות ההורדה. אם לא תספקו זאת, הדפדפן יודיע למשתמש שהגודל לא ידוע, וכתוצאה מכך ייתכן שהמשתמש יהיה גדול יותר שיש סבירות גבוהה שיבטלו את ההורדה. אם מספר ההורדות ברקע חורג מהמספר שצוין כאן, הוא יבוטל. זו
לגמרי אם ההורדה קטנה מ- |
backgroundFetch.fetch
מחזירה הבטחה שמסתיימת באמצעות BackgroundFetchRegistration
. אני
נסביר על הפרטים בהמשך. ההבטחה נדחתה אם המשתמש ביטל את ההסכמה להורדות, או
לא תקין מבין הפרמטרים שסופקו.
מתן בקשות רבות לאחזור יחיד ברקע מאפשר לך לשלב דברים שהם למשתמש יחיד. לדוגמה, סרט עשוי להיות מפוצל לאלפי משאבים (בדרך כלל עם MPEG-DASH), והם כוללים משאבים נוספים כמו תמונות. רמה של משחק יכולה להתפרס על פני מספר רב של משאבי JavaScript, תמונות ואודיו. אבל מבחינת המשתמש, מדובר פשוט "הסרט" או "הרמה".
אחזור קיים ברקע
אפשר לקבל אחזור קיים ברקע כמו:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
...על ידי העברת ה-id של אחזור הרקע הרצוי. הפונקציה get
מחזירה undefined
אם אין
אחזור פעיל ברקע עם המזהה הזה.
אחזור ברקע נחשב ל'פעיל' מרגע הרישום, ועד שהוא מצליח, נכשל או שהוא מתבטל.
אפשר לקבל רשימה של כל האחזורים הפעילים ברקע באמצעות getIds
:
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
הרשמות אחזור ברקע
BackgroundFetchRegistration
(bgFetch
בדוגמאות שלמעלה) כולל:
מאפיינים | |
---|---|
id |
string המזהה של האחזור ברקע. |
uploadTotal |
number מספר הבייטים שיישלחו לשרת. |
uploaded |
number מספר הבייטים שנשלחו בהצלחה. |
downloadTotal |
number הערך שצוין כשנרשמת האחזור ברקע, או אפס. |
downloaded |
number מספר הבייטים שהתקבלו בהצלחה. הערך הזה עשוי לרדת. לדוגמה, אם החיבור נותק וההורדה לא יכולה הופעל מחדש. במקרה כזה, הדפדפן יפעיל מחדש את האחזור של המשאב הזה מההתחלה. |
result |
אחד מהבאים:
|
failureReason |
אחד מהבאים:
|
recordsAvailable |
boolean האם אפשר לגשת לבקשות או לתגובות הבסיסיות? אם המדיניות הזו מוגדרת כ-False, לא ניתן להשתמש ב- |
שיטות | |
abort() |
מחזירה Promise<boolean> ביטול האחזור ברקע. ההבטחה שמוחזרת מופיעה עם ערך True אם האחזור בוטל בהצלחה. |
matchAll(request, opts) |
הפונקציה מחזירה את הערך Promise<Array<BackgroundFetchRecord>> קבלת הבקשות ותשובות. הארגומנטים כאן זהים ל- את המטמון API. קריאה ללא ארגומנטים מחזירה הבטחה לכל הרשומות. המידע על הסיבות האפשריות מפורט כאן. |
match(request, opts) |
הפונקציה מחזירה את הערך Promise<BackgroundFetchRecord> כמו למעלה, אבל עם ערך שחוזר על עצמו ההתאמה הראשונה. |
אירועים | |
progress |
מופעל באחד מהמצבים הבאים: uploaded , downloaded , result או
שינוי אחד (failureReason ). |
התקדמות המעקב
ניתן לעשות זאת דרך האירוע progress
. חשוב לזכור ש-downloadTotal
הוא כל ערך
או 0
אם לא ציינתם ערך.
bgFetch.addEventListener('progress', () => {
// If we didn't provide a total, we can't provide a %.
if (!bgFetch.downloadTotal) return;
const percent = Math.round(bgFetch.downloaded / bgFetch.downloadTotal * 100);
console.log(`Download progress: ${percent}%`);
});
קבלת הבקשות והתשובות
bgFetch.match('/ep-5.mp3').then(async (record) => {
if (!record) {
console.log('No record found');
return;
}
console.log(`Here's the request`, record.request);
const response = await record.responseReady;
console.log(`And here's the response`, response);
});
record
הוא BackgroundFetchRecord
, והוא נראה כך:
מאפיינים | |
---|---|
request |
Request הבקשה שסופקה. |
responseReady |
Promise<Response> התגובה שאוחזרה. התשובה עומדת מאחורי הבטחה כי יכול להיות שהיא עדיין לא התקבלה. ההבטחה תידחה אם האחזור ייכשל. |
אירועים של קובצי שירות (service worker)
אירועים | |
---|---|
backgroundfetchsuccess |
הכול אוחזר בהצלחה. |
backgroundfetchfailure |
אחד או יותר מהאחזורים נכשל. |
backgroundfetchabort |
אחזור אחד או יותר נכשל.
האפשרות הזו שימושית רק אם רוצים לנקות נתונים קשורים. |
backgroundfetchclick |
המשתמש לחץ על ממשק המשתמש של התקדמות ההורדה. |
אובייקטי האירוע כוללים את הדברים הבאים:
מאפיינים | |
---|---|
registration |
BackgroundFetchRegistration |
שיטות | |
updateUI({ title, icons }) |
מאפשר לשנות את הכותרת/הסמלים שהגדרתם בהתחלה. הפעולה הזו היא אופציונלית, אבל מאפשרת לך
במידת הצורך, הוסיפו הקשר נוסף. אפשר לעשות את זה *פעם אחת* במהלך
backgroundfetchsuccess ו-backgroundfetchfailure אירועים. |
תגובה להצלחה או לכשל
כבר ראינו את האירוע progress
, אבל זה מועיל רק כשלמשתמש יש דף פתוח
באתר שלך. היתרון העיקרי של אחזור ברקע הוא שדברים ממשיכים לעבוד גם אחרי שהמשתמש עוזב
או אפילו סוגר את הדפדפן.
אם האחזור ברקע יושלם, ה-Service Worker יקבל את
האירוע backgroundfetchsuccess
ו-event.registration
יהיה הרישום לאחזור ברקע.
אחרי האירוע הזה, הבקשות והתגובות שאוחזרו לא יהיו נגישות יותר, לכן אם תרצו לשמור אותם, להעביר אותם למקום כמו cache API.
כמו ברוב האירועים של קובצי שירות (service worker), כדאי להשתמש ב-event.waitUntil
כדי שה-Service Worker ידע מתי האירוע
הושלם.
לדוגמה, ב-Service Worker:
addEventListener('backgroundfetchsuccess', (event) => {
const bgFetch = event.registration;
event.waitUntil(async function() {
// Create/open a cache.
const cache = await caches.open('downloads');
// Get all the records.
const records = await bgFetch.matchAll();
// Copy each request/response across.
const promises = records.map(async (record) => {
const response = await record.responseReady;
await cache.put(record.request, response);
});
// Wait for the copying to complete.
await Promise.all(promises);
// Update the progress notification.
event.updateUI({ title: 'Episode 5 ready to listen!' });
}());
});
ייתכן שהתשובה נכשלה בגלל שגיאת 404 יחידה, שלא הייתה חשובה לכם, ולכן יכול להיות עדיין שווה להעתיק כמה תגובות למטמון, כפי שמתואר למעלה.
תגובה לקליק
ממשק המשתמש שבו מוצגות התקדמות ההורדה והתוצאה. האירוע backgroundfetchclick
בעוד
באמצעות Service Worker תוכלו להגיב על כך. בדיוק כמו שלמעלה, event.registration
יהיה הרקע
אחזור הרשמה.
לרוב, משתמשים באירוע הזה בפתיחת חלון:
addEventListener('backgroundfetchclick', (event) => {
const bgFetch = event.registration;
if (bgFetch.result === 'success') {
clients.openWindow('/latest-podcasts');
} else {
clients.openWindow('/download-progress');
}
});
מקורות מידע נוספים
תיקון: גרסה קודמת של המאמר הזה נקראה באופן שגוי 'אחזור ברקע' כ'תקן אינטרנט'. ה-API לא נמצא כרגע במסלול הסטנדרטים. אפשר למצוא את המפרט ב-WICG כטיוטה של דוח של קבוצה קהילתית.