בשיעור הזה תלמדו איך להטמיע חוויית חיפוש עמידת בכשלים באמצעות Workbox. אפליקציית ההדגמה (דמו) שבה היא משתמשת מכילה תיבת חיפוש שקוראת לנקודת קצה (endpoint) של שרת ומפנה את המשתמשים לדף HTML בסיסי.
מדידה
לפני שמוסיפים אופטימיזציות, תמיד מומלץ לנתח קודם את המצב הנוכחי של האפליקציה.
- לוחצים על Remix to Edit כדי לאפשר עריכה של הפרויקט.
- כדי לראות תצוגה מקדימה של האתר, לוחצים על View App (הצגת האפליקציה) ואז על Fullscreen (מסך מלא).
בכרטיסייה החדשה שנפתחה, בודקים איך האתר מתנהג כשעוברים למצב אופליין:
- מקישים על Control+Shift+J (או על Command+Option+J ב-Mac) כדי לפתוח את DevTools.
- לוחצים על הכרטיסייה רשתות.
- פותחים את כלי הפיתוח ל-Chrome ובוחרים בחלונית Network (רשת).
- ברשימה הנפתחת של ויסות נתונים, בוחרים באפשרות אופליין.
- באפליקציית הדגמה, מזינים שאילתת חיפוש ולוחצים על הלחצן חיפוש.
מוצג דף השגיאה הרגיל של הדפדפן:
איך מספקים תשובה חלופית
קובץ השירות מכיל את הקוד להוספת הדף אופליין לרשימת המטמון מראש, כך שתמיד אפשר לשמור אותו במטמון באירוע install
של קובץ השירות.
בדרך כלל צריך להורות ל-Workbox להוסיף את הקובץ הזה לרשימת המטמון מראש בזמן ה-build, על ידי שילוב הספרייה עם כלי ה-build שבחרתם (למשל webpack או gulp).
כדי לפשט את התהליך, כבר עשינו זאת בשבילכם. הקוד הבא ב-public/sw.js
עושה את זה:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
בשלב הבא מוסיפים קוד לשימוש בדף אופליין כתגובה חלופית:
- כדי להציג את המקור, לוחצים על הצגת המקור.
- מוסיפים את הקוד הבא לתחתית הקובץ
public/sw.js
:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
הקוד מבצע את הפעולות הבאות:
- הגדרת אסטרטגיית ברירת מחדל מסוג 'רשת בלבד' שחלה על כל הבקשות.
- הכרזה על מנהל שגיאות גלובלי, באמצעות קריאה ל-
workbox.routing.setCatchHandler()
לניהול בקשות שנכשלו. כשהבקשות הן למסמכים, יוחזר דף HTML אופליין חלופי.
כדי לבדוק את הפונקציונליות הזו:
- חוזרים לכרטיסייה השנייה שבה פועלת האפליקציה.
- ברשימה הנפתחת Throttling (בקרת תעבורה), מחזירים את ההגדרה ל-Online (באינטרנט).
- מקישים על הלחצן הקודם ב-Chrome כדי לנווט חזרה לדף החיפוש.
- מוודאים שתיבת הסימון השבתת המטמון מושבתת בכלי הפיתוח.
- לוחצים לחיצה ארוכה על הלחצן טעינה מחדש ב-Chrome ובוחרים באפשרות פינוי המטמון וטעינה מחדש כדי לוודא ש-service worker מעודכן.
- ברשימה הנפתחת Throttling (בקרת קצב העברת נתונים), מגדירים שוב את האפשרות Offline (אופליין).
- מזינים שאילתת חיפוש ולוחצים שוב על הלחצן חיפוש.
דף ה-HTML החלופי מוצג:
שליחת בקשה להרשאה לשליחת התראות
כדי לפשט את הפשטות, הדף אופליין בכתובת views/index_offline.html
כבר מכיל את הקוד לבקשת הרשאות לשליחת התראות בבלוק של סקריפטים בחלק התחתון:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
הקוד מבצע את הפעולות הבאות:
- כשהמשתמש לוחץ על הרשמה לקבלת התראות, מתבצעת קריאה לפונקציה
requestNotificationPermission()
, שמפעילה אתNotification.requestPermission()
כדי להציג את בקשת ההרשאה שמוגדרת כברירת מחדל בדפדפן. ההבטחה משפיעה על ההרשאה שהמשתמש בחר, שיכולה להיותgranted
,denied
אוdefault
. - מעביר את ההרשאה שהוגדרה ל-
showOfflineText()
כדי להציג למשתמש את הטקסט המתאים.
שמירת שאילתות אופליין וניסיון חוזר כשחוזרים למצב אונליין
בשלב הבא, מטמיעים את Workbox Background Sync כדי לשמור שאילתות במצב אופליין, כך שניתן יהיה לנסות אותן שוב כשהדפדפן מזהה שהקישוריות חזרה.
- פותחים את
public/sw.js
כדי לערוך אותו. - מוסיפים את הקוד הבא בסוף הקובץ:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
הקוד מבצע את הפעולות הבאות:
workbox.backgroundSync.Plugin
מכיל את הלוגיקה להוספת בקשות שנכשלו לתור, כדי שניתן יהיה לנסות אותן שוב מאוחר יותר. הבקשות האלה יישמרו ב-IndexedDB.maxRetentionTime
מציין את משך הזמן שבו ניתן לנסות שוב בקשה. במקרה הזה בחרנו 60 דקות (אחרי 60 דקות הנתונים יימחקו).onSync
הוא החלק החשוב ביותר בקוד הזה. הקריאה החוזרת הזו תתבצע כשהחיבור יחזור, כדי לאחזר את הבקשות שבתור ולאחר מכן לאחזר אותן מהרשת.- תגובת הרשת מתווספת למטמון
offline-search-responses
, עם הוספת הפרמטר של השאילתה¬ification=true
, כדי שניתן יהיה לאתר את הרשומה הזו במטמון כשהמשתמש לוחץ על ההתראה.
כדי לשלב את הסנכרון ברקע בשירות, מגדירים אסטרטגיה מסוג NetworkOnly לבקשות לכתובת ה-URL לחיפוש (/search_action
) ומעבירים את bgSyncPlugin
שהוגדר קודם. צריך להוסיף את הקוד הבא בחלק התחתון של public/sw.js
:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
ההגדרה הזו מורה ל-Workbox תמיד לעבור לרשת, וכאשר הבקשות נכשלות, להשתמש בלוגיקה של סנכרון ברקע.
לאחר מכן, מוסיפים את הקוד הבא לתחתית public/sw.js
כדי להגדיר אסטרטגיית שמירת מטמון לבקשות שמגיעות מהתראות. להשתמש באסטרטגיה CacheFirst כדי שניתן יהיה להציג אותם מהמטמון.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
לבסוף, מוסיפים את הקוד להצגת התראות:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
בדיקת התכונה
- חוזרים לכרטיסייה השנייה שבה פועלת האפליקציה.
- ברשימה הנפתחת Throttling (בקרת תעבורה), מחזירים את ההגדרה ל-Online (באינטרנט).
- לוחצים על הלחצן הקודם ב-Chrome כדי לחזור לדף החיפוש.
- כדי לוודא שה-Service Worker מעודכן, לוחצים לחיצה ארוכה על הלחצן Reload ב-Chrome ובוחרים באפשרות Emptycache and קשיח מחדש.
- ברשימה הנפתחת Throttling (בקרת קצב העברת נתונים), מגדירים שוב את האפשרות Offline (אופליין).
- מזינים שאילתת חיפוש ולוחצים שוב על הלחצן חיפוש.
- לוחצים על הרשמה לקבלת התראות.
- כש-Chrome שואל אם אתם רוצים לתת לאפליקציה הרשאה לשלוח התראות, לוחצים על Allow (אישור).
- מזינים שאילתת חיפוש אחרת ולוחצים שוב על הלחצן חיפוש.
- מחזירים את הרשימה הנפתחת Throttling ל-Online (אונליין).
כשהחיבור יחזור, תוצג התראה:
סיכום
ב-Workbox יש הרבה תכונות מובנות שיעזרו לכם לשפר את העמידות והעניין של האפליקציות שלכם מסוג PWA. בקודלאב הזה למדתם איך להטמיע את Background Sync API באמצעות הפשטה של Workbox, כדי להבטיח ששאילתות של משתמשים במצב אופליין לא יאבדו, ואפשר יהיה לנסות שוב אחרי שהחיבור יחזור. הדגמה היא אפליקציית חיפוש פשוטה, אבל אפשר להשתמש בהטמעה דומה בתרחישים ובתרחישי שימוש מורכבים יותר, כולל אפליקציות צ'אט, פרסום הודעות ברשת חברתית וכו'.