עובדי שירות חדשים יותר, כברירת מחדל

tl;dr

החל מ-Chrome 68, בקשות HTTP שמחפשות עדכונים לסקריפט של Service Worker לא מטמון ה-HTTP ממלא זמן רב יותר כברירת מחדל. הוא מטפל בבעיה נפוצה של מפתחים, שבה הגדרה לא מכוונת של כותרת Cache-Control בסקריפט של Service Worker עלולה להוביל ועד לעדכונים מתעכבים.

אם כבר ביטלת את ההסכמה לשמירה במטמון של HTTP עבור הסקריפט /service-worker.js על ידי הצגתו עם Cache-Control: max-age=0, אז לא אמורים להופיע שינויים בגלל ברירת המחדל החדשה או התנהגות המשתמשים.

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

רקע

בכל פעם שעוברים לדף חדש שנכלל בהיקף של קובץ שירות (service worker), קוראים במפורש ל-registration.update() מ-JavaScript, או כשעובד שירות (service worker) "מודיע" דרך אירוע push או sync, הדפדפן במקביל, יבקש את משאב ה-JavaScript שהועבר במקור אל navigator.serviceWorker.register(), כדי לחפש עדכונים בסקריפט של Service Worker.

למטרות המאמר הזה, נניח שכתובת ה-URL שלו היא /service-worker.js, מכיל קריאה יחידה ל-importScripts(), שטוען קוד נוסף שרץ בתוך Service Worker:

// Inside our /service-worker.js file:
importScripts('path/to/import.js');

// Other top-level code goes here.

מה משתנה?

לפני Chrome 68, בקשת העדכון של /service-worker.js נשלחה דרך מטמון ה-HTTP (כמו רוב האחזורים). כלומר, אם הסקריפט נשלח במקור עם Cache-Control: max-age=600, עדכונים במהלך 600 השניות הבאות (10 דקות) לא יגיעו לרשת, לכן ייתכן שהמשתמש לא יקבל את הגרסה העדכנית ביותר של Service Worker. אבל אם הערך של max-age היה גדול מ-86400 (24 שעות), היה נחשב ל-86400, כדי למנוע מצב שבו המשתמשים ייתקעו עם גרסה מסוימת לתמיד.

החל מגרסה 68, המערכת תתעלם ממטמון ה-HTTP כשנשלחת בקשה לעדכונים ל-Service Worker כך שיישומי אינטרנט קיימים עשויים לראות עלייה בתדירות הבקשות סקריפט של Service Worker. הבקשות עבור importScripts עדיין יועברו דרך מטמון ה-HTTP. אבל זה רק ברירת המחדל – אפשרות רישום חדשה, updateViaCache, זמינה עכשיו שמציעה שליטה ההתנהגות הזאת.

updateViaCache

עכשיו המפתחים יכולים להעביר אפשרות חדשה כשהם שולחים קריאה ל-navigator.serviceWorker.register(): הפרמטר updateViaCache. הוא מקבל אחד משלושה ערכים: 'imports', 'all' או 'none'.

הערכים קובעים אם מטמון ה-HTTP הסטנדרטי של הדפדפן ואיך הוא פועל פעיל כששולחים בקשת HTTP כדי לבדוק אם יש משאבים מעודכנים של Service Worker.

  • כשההגדרה מוגדרת לערך 'imports', אף פעם לא מתבצעת בדיקה לגבי מטמון ה-HTTP כשמחפשים עדכונים סקריפט /service-worker.js, אבל המערכת תייעץ לגבי אחזור סקריפטים שיובאו (path/to/import.js, בדוגמה שלנו). זו ברירת המחדל, והיא תואמת להתנהגות שמתחילה ב-Chrome 68.

  • כשההגדרה מוגדרת לערך 'all', נעזרים במטמון ה-HTTP כששולחים בקשות סקריפט /service-worker.js ברמה העליונה, וגם כל סקריפטים שיובאו בתוך השירות עובד, כמו path/to/import.js. האפשרות הזו תואמת להתנהגות הקודמת ב-Chrome, מלפני Chrome 68.

  • כשההגדרה מוגדרת לערך 'none', לא ייעשה שימוש במטמון ה-HTTP כשנשלחות בקשות ברמה העליונה של /service-worker.js או עבור סקריפטים מיובאים, כמו path/to/import.js.

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

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {
    updateViaCache: 'none',
    // Optionally, set 'scope' here, if needed.
  });
}

חיפוש עדכונים לסקריפטים מיובאים

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

הדרך היחידה לאלץ קובץ שירות (service worker) שכבר מותקן לאסוף שינויים סקריפט מיובא היה לשנות את כתובת ה-URL של הסקריפט, בדרך כלל על ידי הוספת semver (למשל, importScripts('https://example.com/v1.1.0/index.js')) או על ידי הכללת גיבוב של את התוכן (למשל, importScripts('https://example.com/index.abcd1234.js')). א' תופעת הלוואי של שינוי כתובת ה-URL המיובאת היא שקובץ השירות (service worker) ברמה העליונה לסקריפט, שבתורו מפעיל תהליך עדכון של Service Worker.

החל מגרסה 78 של Chrome, בכל פעם שמתבצעת בדיקת עדכונים של רמה עליונה בקובץ Service Worker, יתבצעו בדיקות בו-זמנית כדי לקבוע אם או שהתוכן של סקריפטים מיובאים לא השתנה. בהתאם לתרחיש לדוגמה נעשה שימוש ב-Cache-Control כותרות, ייתכן שבדיקות הסקריפט שיובאו יבוצעו על ידי מטמון ה-HTTP אם updateViaCache מוגדר לערך 'all' או 'imports' (כלומר ערך ברירת המחדל), או שהבדיקות עשויות לעבור ישירות אל הרשת אם הערך updateViaCache מוגדר ל-'none'.

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

ההתנהגות של Chrome 78 תואמת להתנהגות של Chrome implemented לפני כמה שנים, ב-Firefox 56. Safari כבר מיישם את ההתנהגות הזו בתור נו.

מה המפתחים צריכים לעשות?

אם ביטלת בפועל את ההסכמה לשמירה במטמון של HTTP עבור הסקריפט /service-worker.js על ידי הצגתו עם Cache-Control: max-age=0 (או ערך דומה), לא אמורים להופיע שינויים כלשהם בעקבות פעולת ברירת המחדל החדשה.

אם שולחים באופן מכוון את הסקריפט /service-worker.js שמופעלת בו שמירה במטמון HTTP, או כי היא רק ברירת המחדל של סביבת האירוח, יכול להיות שיתחיל להופיע עלייה במספר בקשות HTTP נוספות שנשלחות נגד /service-worker.js בשרת שלכם – אלה בקשות שבעבר מילאו מטמון ה-HTTP. אם רוצים להמשיך לאפשר לערך הכותרת Cache-Control להשפיע על עדכניות /service-worker.js, צריך להתחיל להגדיר את updateViaCache: 'all' באופן מפורש מתי רישום ה-Service Worker.

בהתחשב ב"זנב ארוך" של משתמשים בגרסאות ישנות יותר של דפדפן, עדיין מומלץ להמשיך להגדיר את כותרת ה-HTTP Cache-Control: max-age=0 בסקריפטים של Service Worker דפדפנים חדשים יותר עשויים להתעלם מהן.

המפתחים יכולים להשתמש בהזדמנות הזו כדי להחליט אם ברצונם לצרף באופן מפורש את המוצרים המיובאים שלהם סקריפטים ששומרים במטמון HTTP עכשיו, ומוסיפים ב-updateViaCache: 'none' ל-Service Worker שלהם רישום, אם הדבר רלוונטי.

הצגת סקריפטים מיובאים

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

אם רוצים להימנע מתנועת ה-HTTP הנוספת הזו, מגדירים לטווח ארוך Cache-Control כותרות בעת הצגת סקריפטים שכוללים semver או גיבובים (hash) ב כתובות ה-URL שלהם, ומסתמכים על התנהגות ברירת המחדל updateViaCache של 'imports'.

לחלופין, אם אתם רוצים שהסקריפטים המיובאים ייבדקו בתדירות גבוהה ואז יש להקפיד להציג אותם באמצעות Cache-Control: max-age=0, או שאתם משתמשים ב-updateViaCache: 'none'.

קריאה נוספת

"מחזור החיים של Service Worker" וגם "שיטות מומלצות לשמירה במטמון max-age getchas", גם על ידי ג'ייק ארצ'יבלד (Jake Archibald), מומלצים לכל המפתחים שפורסים כל דבר באינטרנט.