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

שיטות מומלצות לתזמון הרישום של עובד השירות.

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

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

טקסט סטנדרטי נפוץ לרישום

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

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

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

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

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

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

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

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

סביר להניח ששרשור ברקע במצב חוסר פעילות לא ישפיע באופן משמעותי. אבל מה קורה אם השרשור הזה לא פעיל, אלא מחליט להתחיל גם להוריד משאבים מהרשת? אם יש לכם חששות לגבי תחרות על המעבד (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 עד אחרי האנימציה, כשסביר להניח שהדפדפן יהיה במצב חוסר פעילות למשך כמה שניות.

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

ביקורים חוזרים

עד עכשיו התמקדנו בחוויית הביקור הראשון, אבל מה ההשפעה של רישום מושהה של עובד שירות על ביקורים חוזרים באתר? יכול להיות שזה יפתיע חלק מהאנשים, אבל לא אמורה להיות השפעה בכלל.

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

לכן, אחרי שיוצרים עובד שירות פעיל, לא משנה מתי קוראים ל-navigator.serviceWorker.register(), או בעצם אם קוראים לו בכלל. אלא אם משנים את כתובת ה-URL של סקריפט ה-service worker, הערך של navigator.serviceWorker.register() הוא למעשה no-op (פעולה ללא תוצאה) במהלך ביקורים הבאים. מתי הוא נקרא לא רלוונטי.

למה כדאי להירשם מוקדם

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

בדיקה של דברים

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

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

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

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

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

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

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

סיכום

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

כדי לוודא שהרישום הראשוני של ה-service worker יתעכב עד לאחר טעינת הדף הראשון, אפשר להשתמש בקוד הבא:

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