הוספות ל-cache.addAll() ול-ImportScripts() בגרסה 71 ל-Chrome

מפתחים שמשתמשים ב-service work וב-Cache Storage API צריכים לשים לב לשני שינויים קטנים שיושקו ב-Chrome 71. שני השינויים משפרים את ההטמעה של Chrome בהתאם למפרט ולדפדפנים אחרים.

אי אפשר להשתמש ב-ImportScripts() אסינכרוניים

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

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

אבל כדי שזה יעבוד, הדפדפן צריך לדעת שלא יהיה קוד "מפתיע" שמיובא ל-Service Worker אחרי ההתקנה הראשונית. לפי מפרט Service worker, קריאה ל-importScripts() אמורה לפעול רק במהלך הביצוע הסינכרוני של הסקריפט ברמה העליונה של Service Worker, או במקרה הצורך, באופן אסינכרוני בתוך ה-handler של install.

לפני Chrome 71, אפשר להפעיל קריאה אסינכרונית אל importScripts() מחוץ ל-handler של install. החל מ-Chrome 71, הקריאות האלה גורמות לחריגה בתחילת ההפעלה (אלא אם אותה כתובת URL יובאה בעבר ב-handler של install), שתואמות להתנהגות בדפדפנים אחרים.

במקום קוד כזה:

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

קוד של קובץ השירות (service worker) אמור להיראות כך:

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

מתבצעת הוצאה משימוש של כתובות URL חוזרות שהועברו ל-cache.addAll()

אם אתם משתמשים ב-Cache Storage API לצד Service Worker, קיים עוד שינוי קטן ב-Chrome 71 שיתאים למפרט הרלוונטי. כשאותה כתובת URL מועברת כמה פעמים לקריאה יחידה אל cache.addAll(), במפרט מצוין שההבטחה שהוחזרה על ידי הקריאה אמורה לדחות.

בגרסאות שקודמות לגרסה 71 של Chrome, השירות לא זוהה, והמערכת הייתה מתעלמת מכתובות ה-URL הכפולות.

צילום מסך של הודעת האזהרה במסוף Chrome
החל מגרסה 71 של Chrome, תופיע הודעת אזהרה המתועדת במסוף.

הרישום ביומן הזה הוא הקדמה לגרסה 72 של Chrome, שבה במקום להציג רק אזהרה שנרשמה ביומן, כתובות URL כפולות יובילו לדחייה של cache.addAll(). כשקוראים ל-cache.addAll() כחלק משרשרת ההבטחה שמעבירים אל InstallEvent.waitUntil(), כפי שנהוג בדרך כלל, הדחייה הזו עלולה לגרום לכשלים בהתקנה של קובץ השירות (service worker).

הנה דרכים שבהן אתם עלולים להיתקל בבעיות:

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

ההגבלה הזו חלה רק על כתובות ה-URL שמועברות בפועל אל cache.addAll(). שמירה במטמון של שתי תגובות מקבילות עם כתובות URL שונות – כמו '/' ו-'/index.html' – לא תגרום לדחייה.

בדיקה נרחבת של ההטמעה של Service Worker

בשלב הזה, Service Workers מיושמים באופן נרחב בכל הדפדפנים 'ירוקי-עד' העיקריים. אם אתם בודקים באופן קבוע את Progressive Web App מול מספר דפדפנים, או אם יש לכם מספר משמעותי של משתמשים שלא משתמשים ב-Chrome, סביר להניח שכבר גילית את חוסר העקביות ועדכנת את הקוד. אבל אם לא הבחנתם בהתנהגות הזו בדפדפנים אחרים, רצינו להסביר את השינוי לפני שינוי ההתנהגות של Chrome.