הסרת עובדי שירות עם באגים

לפעמים מתבצעת פריסה של קובץ שירות (service worker) עם באגים, ואז יש בעיות. לדוגמה, ניתן לנתח קובץ שירות (service worker) בזמן הרישום ולהשלים את ההתקנה בהצלחה. עם זאת, קוד באגים באירוע fetch עלול לגרום לכך שהוא לא יגיב לבקשות, וכתוצאה מכך ייווצר דף ריק. אפשרות נוספת היא שתגי העיצוב של דף נשמרים במטמון בצורה אגרסיבית, ו-Service Worker מחזיר רק תגובות של תגי עיצוב לא פעילים מ-Cache בביקורים הבאים.

יש דרכים רבות שבהן קובץ שירות (service worker) עלול להחזיר למצב הקודם, וזו בעיה מפחידת באתר בסביבת ייצור. למרות זאת, לא הולכים לאיבוד. יש דרכים לפתור את הבעיה ולחזור למסלול.

פריסה של Service Worker ללא תפעול

בדרך כלל כל מה שצריך כדי להתמודד עם קובץ שירות (service worker) עם באגים הוא לפרוס קובץ שירות (service worker) בסיסי ללא תפעול, שמתקין ומפעיל מיד ללא גורם handler של אירועים של fetch:

// sw.js

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker's control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({
    type: 'window'
  }).then(windowClients => {
    windowClients.forEach((windowClient) => {
      windowClient.navigate(windowClient.url);
    });
  });
});

קובץ השירות הזה יתקין ויפעיל באופן מיידי על ידי התקשרות אל self.skipWaiting() באירוע install. לחלופין, אפשר לפרוס קוד נוסף באירוע activate כדי לכפות טעינה מחדש של כרטיסיות פתוחות עם WindowClient שנמצא בשליטת ה-Service Worker.

חשוב מאוד ש-Service worker ללא תפעול לא יכיל גורם handler של אירועים מסוג fetch. כש-Service Worker לא מטפל בבקשות, הבקשות האלה עוברות לדפדפן כאילו לא נמצא קובץ שירות (service worker). לאחר פריסה של קובץ שירות ללא תפעול (service worker), ניתן לתקן את הבאג ולפרוס אותו כעדכון מאוחר יותר.

הגישה הזו עובדת בין היתר כי לדפדפנים יש אמצעי הגנה חזקים נגד מיקום קובצי שירות (service worker) במטמון ה-HTTP, ומאחר שהם מבצעים בדיקות כל-בייט של התוכן של Service Worker כדי לאתר עדכונים. הגדרות ברירת המחדל האלה מאפשרות לפרוס כלי חלופי ללא תפעול כדי לתקן את הבעיה במהירות.

פעולות נוספות שצריך לבצע

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

מה אם אתם לא יודעים את כתובת ה-URL של ה-Service Worker הישן?

לפעמים כתובת URL של קובץ שירות (service worker) שהותקן בעבר אינה ידועה. יכול להיות שהסיבה לכך היא שהוא מבוסס על גרסה (למשל, מכיל גיבוב בשם הקובץ). במקרה הזה יכול להיות מאתגר לפרוס Service Worker ללא תפעול שתואם לכתובת ה-URL של כל אחד מה-Service Worker הישן שעשוי להיות רשום. זה מנוגד לשיטות המומלצות, כי סביר להניח שהמפתחים לא יזכרו כל גיבוב (hash) של כל גרסה של Service Worker שנפרסה.

למרבה המזל, כותרת מועילה של בקשת HTTP נשלחת עם בקשה לסקריפט של Service Worker: Service-Worker. בשרת האינטרנט, מחפשים את הכותרת הזו ומיירטים את הבקשה כדי להגיש במקום זאת קובץ שירות (service worker) ללא תפעול. ביצוע הפעולה הזו תלוי בשרת האינטרנט ובסטאק הקצה העורפי שבהם נעשה שימוש, לכן יש לעיין במסמכי התיעוד של השפה הרלוונטית כדי לדעת כיצד לעשות זאת.

לגבי פריסות עתידיות של Service Worker, הקפידו להשתמש בשמות של נכסים שאין להם גרסאות (לדוגמה, sw.js). זה יהיה הרבה פחות מסובך בהמשך.

הגדרת הכותרת Clear-Site-Data

חלק מהדפדפנים יבטלו את הרישום של כל ה-Service Workers של מקור אם מוגדרת כותרת תגובה Clear-Site-Data עם הערך 'storage'. עם זאת, יש כמה דברים שכדאי לשים לב אליהם בגישה זו:

  • אזהרה: הפעולה הזו תגרום למחיקת כל האחסון של המקור המשויך. זה כולל אחסון מסוג localStorage, IndexedDB, sessionStorage ועוד (אבל לא מטמון ה-HTTP של המקור).
  • הכותרת הזו לא נתמכת בכל הדפדפנים.

מאחר שהתמיכה בכותרת הזו אינה מלאה, לא ניתן להסתמך עליה בלבד כדי לפתור את הבעיה. לכן מומלץ להתייחס אל Clear-Site-Data כאמצעי להטמעה בנוסף לפריסה של קובץ שירות (service worker) ללא תפעול.

הנזק אינו בלתי הפיך

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

אם צריך לפרוס worker ללא תפעול כדי לתקן את המצב, כדאי להקדיש זמן אחרי מעשה כדי להבין בדיוק מה השתבש. בעתיד, יש לוודא שה-Service Worker מטפל רק בבקשות שהוא צפוי לטפל בו. מומלץ לבדוק לעיתים קרובות ב-Staging ולפרוס עדכונים רק כשיש לך ביטחון.