שיטות מומלצות לשמירת מצב האפליקציה באמצעות IndexedDB

שיטות מומלצות לסנכרון מצב האפליקציה בין IndexedDB לבין ספריות פופולריות לניהול מצבים.

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

אחסון מצב האפליקציה ב-IndexedDB יכול להיות דרך מצוינת לזרז את זמן הטעינה בביקורים חוזרים. לאחר מכן, האפליקציה יכולה להסתנכרן עם כל שירותי ה-API ברקע ולעדכן את ממשק המשתמש בנתונים חדשים באופן עצל, תוך שימוש באסטרטגיית stale-while-revalidate.

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

הקפידו על עקביות באפליקציה

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

יכול להיות שהכתיבה לאחסון תיכשל

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

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

יכול להיות שהמשתמש שינה או מחק את הנתונים השמורים

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

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

יכול להיות שהנתונים השמורים לא עדכניים

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

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

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

שמירה על ביצועי האפליקציה

אחת התכונות העיקריות של IndexedDB היא ה-API האסינכרוני שלו, אבל אל תטעו לחשוב שאתם לא צריכים לדאוג לגבי הביצועים כשאתם משתמשים בו. יש כמה מקרים שבהם שימוש לא נכון עדיין יכול לחסום את ה-thread הראשי, מה שעלול לגרום לחוסר תגובה.

ככלל, פעולות קריאה וכתיבה ב-IndexedDB לא צריכות להיות גדולות יותר מהנדרש לנתונים שאליהם ניגשים.

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

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

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

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

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

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

מסקנות

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

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

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