כדי לתכנן אפליקציה שמנצלת את מלוא היתרונות של הטכנולוגיה שמאפשרת ל-PWA להיות אמין, מתקין ויעיל, צריך להבין את האפליקציה ואת המגבלות שלה ולבחור ארכיטקטורה מתאימה לשניהם.
SPA לעומת אישור על ידי גורמים מרובים
כיום יש שני דפוסי ארכיטקטורה עיקריים בפיתוח אינטרנט: אפליקציות בדף יחיד (SPA) ואפליקציות בכמה דפים (MPA).
אפליקציות של דף יחיד מוגדרות על ידי JavaScript בצד הלקוח ששולט ברוב או בכל העיבוד של HTML בדף על סמך נתונים שאוחזרו על ידי האפליקציה או שסופקו לה. האפליקציה מבטלת את העדפות הניווט המובנות של הדפדפן ומחליפת אותן בפונקציות הניתוב וטיפול התצוגה שלה.
באפליקציות מרובות דפים יש בדרך כלל HTML שעבר עיבוד מראש שנשלח ישירות לדפדפן, לרוב משופר באמצעות JavaScript בצד הלקוח אחרי שהדפדפן סיים לטעון את ה-HTML, והוא מסתמך על מנגנוני הניווט המובנים בדפדפן כדי להציג את התצוגות הבאות.
אפשר להשתמש בשתי הארכיטקטורות כדי ליצור אפליקציות PWA.
לכל אחת מהן יש יתרונות וחסרונות, ובחירת האפשרות המתאימה לתרחיש לדוגמה ולהקשר שלכם היא המפתח לספק למשתמשים חוויה מהירה ואמינה.
אפליקציות בדף יחיד
- בעיקר עדכונים אטומיים בדף.
- יחסי תלות בצד הלקוח שנטענים בזמן ההפעלה.
- הטעינות הבאות יהיו מהירות יותר בגלל השימוש במטמון.
- עלות טעינה ראשונית גבוהה.
- הביצועים תלויים בחומרה של המכשיר ובחיבור לרשת.
- נדרשת מורכבות נוספת של האפליקציה.
אפליקציות בדף יחיד מתאימות לארכיטקטורה טובה אם:
- האינטראקציה של המשתמשים מתמקדת בעיקר בעדכונים אטומיים של נתונים מקושרים שמוצגים באותו דף, למשל לוח בקרה של נתונים בזמן אמת או אפליקציית עריכת וידאו.
- לאפליקציה יש יחסי תלות בצד הלקוח בלבד לצורך אתחול, למשל ספק אימות של צד שלישי עם עלות הפעלה גבוהה מאוד.
- הנתונים הנדרשים כדי שתצוגה תיטען מבוססים על הקשר ספציפי בצד הלקוח בלבד, למשל, הצגת אמצעי בקרה של חומרה מחוברת.
- האפליקציה קטנה ופשוטה, כך שהגודל והמורכבות שלה לא משפיעים על החסרונות שמפורטים למעלה.
יכול להיות ש-SPA לא תהיה בחירה טובה לארכיטקטורה אם:
- ביצועי הטעינה הראשונית הם חיוניים. בדרך כלל, ב-SPA צריך לטעון יותר JavaScript כדי לקבוע מה לטעון ואיך להציג אותו. זמן הניתוח והביצוע של קוד ה-JavaScript הזה, בשילוב עם אחזור התוכן, איטי יותר משליחת קובץ HTML שעבר עיבוד.
- האפליקציה פועלת בעיקר במכשירים עם עוצמה נמוכה עד בינונית. מאחר ש-SPA תלויים ב-JavaScript לעיבוד, חוויית המשתמש תלויה באופן משמעותי יותר בעוצמה של המכשיר הספציפי שלהם מאשר ב-MPA.
מכיוון ששירותי SPA צריכים להחליף את הניווט המובנה של הדפדפן בניתוב שלהם, השירותים האלה מחייבים רמה מינימלית של מורכבות סביב עדכון יעיל של התצוגה הנוכחית, ניהול שינויים בניווט וניקוי תצוגות קודמות שהדפדפן היה מטפל בהן. כתוצאה מכך, קשה יותר לתחזק אותן באופן כללי במכשיר של המשתמש ולהוסיף להן מיסוי.
אפליקציות עם כמה דפים
- בעיקר עדכונים בדף מלא.
- מהירות העיבוד הראשונית היא קריטית.
- סקריפט בצד הלקוח יכול לשפר את האתר.
- לתצוגות משניות נדרשת קריאה נוספת לשרת.
- ההקשר לא מועבר בין התצוגות.
- נדרש שרת או עיבוד מראש.
אפליקציות עם כמה דפים הן בחירה ארכיטקטונית טובה אם:
- האינטראקציה של המשתמש מתמקדת בעיקר בתצוגות של פריט נתונים יחיד עם נתונים אופציונליים שמבוססים על הקשר, למשל אפליקציית חדשות או אפליקציית מסחר אלקטרוני.
- מהירות העיבוד הראשונית היא קריטית, כי שליחת קובץ HTML שכבר עבר עיבוד לדפדפן מהירה יותר מאשר הרכבת קובץ HTML מבקשת נתונים אחרי הטעינה, הניתוח וההפעלה של חלופה מבוססת-JavaScript.
- אפשר לכלול אינטראקטיביות או הקשר בצד הלקוח כתוספת לאחר הטעינה הראשונית. לדוגמה, אפשר להוסיף שכבת פרופיל לדף שעבר רינדור או להוסיף רכיבים משניים בצד הלקוח שמושפעים מההקשר.
יכול להיות שארכיטקטורת MPA לא מתאימה אם:
- הורדה מחדש, ניתוח מחדש והפעלה מחדש של JavaScript או CSS הם יקרים מאוד. אפשר לצמצם את החיסרון הזה באפליקציות PWA עם קובצי שירות.
- הקשר בצד הלקוח, כמו מיקום המשתמש, לא עובר בצורה חלקה בין הצפיות, וקבלת ההקשר מחדש עלולה להיות יקרה. צריך לצלם ולאחזר אותו, או לבקש אותו מחדש בין התצוגות.
מכיוון שתצוגות ספציפיות צריכות לעבור עיבוד דינמי על ידי השרת או לעבד אותן מראש לפני הגישה אליהן, מה שעלול להגביל את האירוח או להוסיף את מורכבות הנתונים.
איזו אפשרות כדאי לבחור?
למרות היתרונות והחסרונות האלה, שתי הארכיטקטורות תקינות ליצירת אפליקציית ה-PWA. אפשר אפילו לשלב ביניהם בחלקים שונים של האפליקציה, בהתאם לצרכים של האפליקציה. לדוגמה, דפי האפליקציה בחנות צריכים להיות בנויים לפי ארכיטקטורת MPA, ותהליך התשלום צריך להיות לפי ארכיטקטורת SPA.
לא משנה מה תבחרו, השלב הבא הוא להבין איך להשתמש בצורה הטובה ביותר ב-service workers כדי לספק את חוויית המשתמש הטובה ביותר.
עוצמת קובץ השירות (service worker)
ל-service worker יש הרבה יכולות מעבר לניתוב בסיסי והעברת תשובות מהרשת וממטמון. אנחנו יכולים ליצור אלגוריתמים מורכבים שיכולים לשפר את חוויית המשתמש ואת הביצועים.
קובץ שירות כולל (SWI)
דפוס חדש לשימוש בקובצי שירות כחלק בלתי נפרד מארכיטקטורת האתר הוא 'קובצי שירות שכלולים' (SWI). SWI מחלק נכסים נפרדים, בדרך כלל דף HTML, לחלקים על סמך הצרכים שלהם לשמירת נתונים במטמון, ולאחר מכן מחבר אותם מחדש בקובץ השירות (service worker) כדי לשפר את העקביות, הביצועים והאמינות, תוך צמצום גודל המטמון.
התמונה הזו היא דף אינטרנט לדוגמה. הדף כולל חמישה קטעים שונים שמחלקים את הדף ל-5 חלקים:
- פריסה כוללת.
- כותרת גלובלית (פס כהה בחלק העליון).
- אזור התוכן (השורות והתמונה שבפינה הימנית התחתונה).
- סרגל הצד (סרגל גבוה כהה-בינוני בפינה השמאלית העליונה).
- כותרת תחתונה (פס כהה בתחתית המסך).
הפריסה הכללית
סביר להניח שהפריסה הכוללת לא תשתנה לעיתים קרובות ואין לה יחסי תלות. הוא מתאים לאחסון מראש.
כותרת עליונה ותחתונה
הכותרת העליונה והכותרת התחתונה הגלובליות מכילות רכיבים כמו התפריט העליון והכותרת התחתונה של האתר, והן מהוות אתגר מיוחד: אם הדף נשמר במטמון כמכלול, הרכיבים האלה עשויים להשתנות בין טעינות הדף, בהתאם למועד שבו הדף הנתון נשמר במטמון.
כשמפרידים אותם ומאחסנים אותם במטמון בנפרד מהתוכן, אפשר להבטיח שהמשתמשים תמיד יקבלו את אותה גרסה, ללא קשר למועד שבו היא אוחסנה במטמון. מכיוון שהם מתעדכנים לעיתים רחוקות, הם גם מועמדים טובים לאחסון במטמון מראש. עם זאת, יש להם יחסי תלות: קובצי ה-CSS ו-JavaScript של האתר.
CSS ו-JavaScript
באופן אידיאלי, כדאי לשמור במטמון את ה-CSS וה-JavaScript של האתר באופן לא פעיל, תוך כדי אימות מחדש של האסטרטגיה, כדי לאפשר עדכונים מצטברים בלי שיהיה צורך לעדכן את ה-Service Worker, כמו במקרה של נכסים שנשמרו מראש במטמון. עם זאת, צריך גם לשמור על גרסה מינימלית בכל פעם ש-service worker מתעדכן בכותרת או בכותרת תחתונה גלובלית חדשה. לכן, גם המטמון שלהם צריך להתעדכן בגרסה האחרונה של הנכסים כשה-service worker מתקין אותם.
אזור תוכן
השלב הבא הוא אזור התוכן. בהתאם לתדירות העדכונים, מומלץ להגדיר כאן רשת ראשונה או רשת לא פעילה בזמן האימות מחדש. צריך להוסיף תמונות למטמון באמצעות אסטרטגיה שמתמקדת במטמון, כפי שהוסבר קודם.
סרגל צד
לסיום, בהנחה שהתוכן בסרגל הצד מכיל תוכן משני, כמו תגים ופריטים קשורים, אין מספיק חשיבות לשליפה מהרשת. אפשר להשתמש באסטרטגיה 'לא עדכני בזמן אימות מחדש'.
עכשיו, אחרי שעברתם את כל השלבים האלה, יכול להיות שתחשבו שאפשר לבצע שמירה במטמון לכל קטע רק באפליקציות בדף יחיד. עם זאת, אם תשתמשו בתבניות בהשראת include בצד הקצה או include בצד השרת ב-service worker, עם כמה תכונות מתקדמות של service worker, תוכלו לעשות זאת בכל אחת מהארכיטקטורות.
התנסות עצמית
אפשר לנסות את ה-service worker שכלול בקודלאב הבא:
הצגת התשובות באופן שוטף
אפשר ליצור את הדף הקודם באמצעות מודל מעטפת האפליקציה בעולם ה-SPA, שבו מעבירים את מעטפת האפליקציה למטמון, ולאחר מכן מציגים אותה, והתוכן נטען בצד הלקוח. בזכות ההשקה של ה-Stream API וזמינותו הרחבה, אפשר לשלב את מעטפת האפליקציה ואת התוכן ב-Service Worker ולהעביר בסטרימינג לדפדפן, וכך נהנים מגמישות בשמירה במטמון של מעטפת האפליקציה במהירות של MPA.
הסיבה לכך היא:
- ניתן ליצור שידורי סטרימינג באופן אסינכרוני, כך שקטעי סטרימינג שונים יגיעו ממקורות אחרים.
- מגיש הבקשה לשידור יכול להתחיל לעבוד על התגובה ברגע שחלק הנתונים הראשון זמין, במקום להמתין להשלמת הפריט כולו.
- מנתחנים שעברו אופטימיזציה לשידור, כולל הדפדפן, יכולים להציג את התוכן של השידור באופן הדרגתי לפני שהוא מסתיים, וכך להאיץ את הביצועים של התגובה.
בזכות שלושת המאפיינים האלה של שידורים, לארכיטקטורות שמבוססות על סטרימינג בדרך כלל יש ביצועים נתפסים מהירים יותר מאשר לארכיטקטורות שלא מבוססות על סטרימינג.
העבודה עם Streams API יכולה להיות מאתגרת כי הוא מורכב ורמת הקוד שלו נמוכה. למרבה המזל, יש מודול של Workbox שיכול לעזור בהגדרת תגובות בסטרימינג לשירותי ה-Worker.
דומיינים, מקורות והיקף של אפליקציות PWA
עובדי אינטרנט, כולל קובצי שירות (service worker) ורכיבי אחסון, ואפילו חלון של PWA מותקן, מנוהלים כולם לפי אחד ממנגנוני האבטחה הקריטיים ביותר באינטרנט: אותה מדיניות מקור זהה. באותו מקור, הרשאות ניתנות, אפשר לשתף נתונים ושירות העבודה יכול לתקשר עם לקוחות שונים. מחוץ לאותו מקור, ההרשאות לא ניתנות באופן אוטומטי והנתונים מבודדים ולא ניתן לגשת אליהם בין מקורות שונים.
מדיניות מקור זהה
שתי כתובות URL מוגדרות כבעלות מקור זהה אם הפרוטוקול, היציאה והמארח זהים.
לדוגמה: ל-https://squoosh.app
ול-https://squoosh.app/v2
יש אותו מקור, אבל http://squoosh.app
, https://squoosh.com
, https://app.squoosh.app
ו-https://squoosh.app:8080
יש מקורות שונים. מידע נוסף ודוגמאות זמינים במאמרי העזרה ל-MDN של מדיניות המקור הזהה.
שינוי תת-דומיינים הוא לא הדרך היחידה שבה מארח יכול לשנות. כל מארח מורכב מדומיין ברמה עליונה (TLD), מדומיין ברמה שנייה (SLD) ומאפס תוויות או יותר (שנקראות לפעמים תת-דומיינים), שמפרידים ביניהם נקודות, וקוראים אותם מימין לשמאל בכתובת URL. שינוי באחד מהפריטים גורם לשימוש במארח אחר.
במודול לניהול חלונות כבר ראינו איך הדפדפן מתוך האפליקציה נראה כשמשתמש מנווט למקור אחר מ-PWA מותקן.
הדפדפן הזה באפליקציה יופיע גם אם לאתרים יש את אותו TLD ו-SLD, אבל עם תוויות שונות, כי הם נחשבים אז למקורות שונים.
אחד מהיבטים המרכזיים של מקור בהקשר של גלישה באינטרנט הוא אופן הפעולה של האחסון וההרשאות. במקור אחד יש תכונות רבות שכל התוכן והאפליקציות לנייד (PWA) שנמצאים בו חולקים, כולל:
- מכסת האחסון והנתונים (IndexedDB, קובצי cookie, אחסון באינטרנט, אחסון במטמון).
- רישומים של קובצי שירות (service worker).
- הרשאות שהתקבלו או נדחו (כמו הודעות דחיפה לאינטרנט, מיקום גיאוגרפי, חיישנים).
- הרשמות לקבלת התראות מאפליקציית אינטרנט.
כשעוברים ממקור אחד למקור אחר, כל הגישה הקודמת מבוטלת, כך שצריך להעניק שוב את ההרשאות, ולאפליקציית ה-PWA אין גישה לכל הנתונים ששמורים באחסון.