רישום של קובץ שירות (service worker)

שיטות מומלצות לתזמון הרישום של קובץ השירות (service worker).

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

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

תבנית סטנדרטית נפוצה לרישום

אם קראתם בעבר על Service Workers, סביר להניח שנתקלתם בתבנית בוילרפלייט דומה מאוד לגורמים הבאים:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
}

לפעמים העדכון עשוי ללוות כמה הצהרות console.log() או קוד שמזהה עדכון של רישום קודם של קובץ שירות (service worker) כדי ליידע את המשתמשים לרענן את הדף. אבל אלו רק שינויים קלים בשורות הקוד הסטנדרטיות.

אז האם יש ניואנסים כלשהם לגבי navigator.serviceWorker.register? האם יש שיטות מומלצות שכדאי לפעול לפיהן? לא מפתיע (גם אם המאמר הזה לא מסתיים כאן), התשובה לשניהם היא 'כן!'

ביקור ראשון של משתמש

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

כמפתחים, חשוב לוודא שהדפדפן מקבל במהירות את הקבוצה המינימלית של המשאבים הקריטיים הדרושים להצגת דף אינטראקטיבי. כל מה שמאט את אחזור התגובות האלה הוא האויב של חוויית הזמן האינטראקטיבית המהירה.

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

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

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

שיפור התבנית

הפתרון הוא לשלוט בהפעלה של קובץ השירות (service worker) על ידי בחירה מתי להפעיל את navigator.serviceWorker.register(). כלל אצבע פשוט הוא לעכב את הרישום עד להפעלת load event בתאריך window, באופן הבא:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}

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

באופן דומה, אם באפליקציית האינטרנט שלכם נעשה שימוש ב-framework שמבצעת הגדרה נוספת אחרי שהדף נטען, צריך לחפש אירוע ספציפי ל-framework שמעיד על השלמת העבודה.

הביקורים הבאים

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

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

אז ברגע שיש קובץ שירות (service worker) פעיל, לא משנה מתי מתקשרים אל navigator.serviceWorker.register(), ולמעשה קוראים לזה בכלל. אם לא משנים את כתובת ה-URL של הסקריפט של קובץ השירות, הערך navigator.serviceWorker.register() נחשב למעשה לא פעיל בביקורים הבאים. מה שנקרא לא רלוונטי.

סיבות להרשמה מוקדמת

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

בודקים דברים

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

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

תנועה ברשת עם רישום מוקדם.

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

תנועה ברשת עם רישום מאוחר.

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

מקבלים נקודות בונוס אם מבצעים בדיקה כזו ממכשיר לא משודרג ברשת סלולרית אמיתית. תוכלו לנצל את יכולות ניפוי הבאגים מרחוק של Chrome כדי לחבר טלפון Android למחשב באמצעות USB, ולוודא שהבדיקות שאתם מפעילים משקפות את החוויה בפועל של רבים מהמשתמשים.

סיכום

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

דרך פשוטה לעכב את הרישום הראשוני של ה-Service Worker עד לאחר טעינת הדף הראשון היא לבצע את הפעולות הבאות:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}