שיטות מומלצות לסנכרון מצב האפליקציה בין IndexedDB לבין ספריות פופולריות לניהול מצב.
כשמשתמש טוען אתר או אפליקציה בפעם הראשונה, לרוב נדרש זמן רב כדי ליצור את מצב האפליקציה הראשוני שמשמש ליצירת ממשק המשתמש. לדוגמה, לפעמים האפליקציה צריכה לאמת את המשתמש בצד הלקוח, ואז לשלוח כמה בקשות API כדי לקבל את כל הנתונים הדרושים להצגה בדף.
אחסון מצב האפליקציה ב-IndexedDB יכול להיות דרך מצוינת להאיץ את זמן הטעינה של ביקורים חוזרים. לאחר מכן, האפליקציה יכולה לסנכרן עם כל שירותי ה-API ברקע ולעדכן את ממשק המשתמש בנתונים חדשים באופן עצל, באמצעות אסטרטגיית stale-while-revalidate.
עם זאת, כשמשתמשים ב-IndexedDB יש הרבה דברים חשובים שצריך לקחת בחשבון, ויכול להיות שהם לא ברורים באופן מיידי למפתחים חדשים בממשקי ה-API. במסמך הזה נענה על שאלות נפוצות ונציג כמה מהדברים החשובים ביותר שכדאי לזכור כששומרים את מצב האפליקציה ב-IndexedDB.
שמירה על עקביות באפליקציה
חלק גדול מהמורכבויות של IndexedDB נובעות מהעובדה שיש כל כך הרבה גורמים שאתם (המפתחים) לא שולטים בהם. בקטע הזה נסקור הרבה מהבעיות שחשוב לזכור כשעובדים עם IndexedDB.
יכול להיות שפעולות כתיבה באחסון ייכשל
שגיאות בכתיבה ב-IndexedDB יכולות לקרות מסיבות שונות, ובמקרים מסוימים הסיבות האלה לא בשליטתכם כמפתחים. לדוגמה, בדפדפנים מסוימים אי אפשר לכתוב ב-IndexedDB במצב גלישה פרטי. יכול להיות גם שמשתמש משתמש במכשיר שכמעט אין בו מקום פנוי בדיסק, והדפדפן לא יאפשר לכם לאחסן דבר.
לכן חשוב מאוד שתמיד תטמיעו טיפול תקין בטעויות בקוד של IndexedDB. המשמעות היא גם שכדאי בדרך כלל לשמור את מצב האפליקציה בזיכרון (בנוסף לאחסון), כדי שממשק המשתמש לא יקרוס כשהאפליקציה פועלת במצב גלישה פרטית או כשאין מקום פנוי באחסון (גם אם חלק מהתכונות האחרות של האפליקציה שמחייבות אחסון לא יפעלו).
יכול להיות שהמשתמש שינה או מחק את הנתונים השמורים
בניגוד למסדי נתונים בצד השרת, שבהם אפשר להגביל גישה לא מורשית, למסדי נתונים בצד הלקוח יש גישה לתוספים לדפדפן ולכלים למפתחים, והמשתמשים יכולים למחוק אותם.
יכול להיות שמשתמשים לא משנים לעיתים קרובות את הנתונים ששמורים באופן מקומי, אבל הם מנקים אותם לעיתים קרובות. חשוב שהאפליקציה תוכל לטפל בשני המקרים האלה ללא שגיאות.
יכול להיות שהנתונים השמורים לא עדכניים
בדומה לקטע הקודם, גם אם המשתמש לא שינה את הנתונים בעצמו, יכול להיות שהנתונים שנשמרו אצלו נכתבו על ידי גרסה קודמת של הקוד שלכם, אולי גרסה עם באגים.
ל-IndexedDB יש תמיכה מובנית בגרסאות של סכימות ובשדרוגים באמצעות השיטה IDBOpenDBRequest.onupgradeneeded()
. עם זאת, עדיין צריך לכתוב את קוד השדרוג כך שיוכל לטפל במשתמש שמגיע מגרסה קודמת (כולל גרסה עם באג).
בדיקות יחידה יכולות להיות מאוד מועילות כאן, כי לעיתים קרובות אי אפשר לבדוק באופן ידני את כל התרחישים והדרכים האפשריים לשדרוג.
שמירה על ביצועים טובים באפליקציה
אחת מהתכונות העיקריות של IndexedDB היא ה-API האסינכרוני שלה, אבל אל תתנו לזה להטעות אתכם לחשוב שאין צורך לדאוג לגבי הביצועים כשמשתמשים בו. יש כמה מקרים שבהם שימוש לא תקין עדיין יכול לחסום את השרשור הראשי, מה שעלול להוביל לכך שהמכשיר לא יגיב.
ככלל, פעולות הקריאה והכתיבה ב-IndexedDB לא צריכות להיות גדולות יותר מהנדרש לנתונים שאתם צריכים לגשת אליהם.
IndexedDB מאפשר לאחסן אובייקטים גדולים ומקוננים כרשומה אחת (וזוהי שיטה נוחה למדי מנקודת המבט של המפתחים), אבל כדאי להימנע ממנה. הסיבה לכך היא שכאשר IndexedDB מאחסן אובייקט, הוא צריך קודם ליצור עותק משכפל מובנה של האובייקט הזה, ותהליך היצירה של העותק המשכפל המובנה מתבצע בשרשור הראשי. ככל שהאובייקט גדול יותר, כך זמן החסימה יהיה ארוך יותר.
הבעיה הזו יוצרת אתגרים מסוימים בתכנון השמירה של מצב האפליקציה ב-IndexedDB, כי רוב הספריות הפופולריות לניהול מצב (כמו Redux) עובדות על ידי ניהול של כל עץ המצב כאובייקט JavaScript יחיד.
לניהול המצב בדרך הזו יש יתרונות רבים, ויכול להיות שזה מפתה ונוח לאחסן את כל עץ המצב כרשומה אחת ב-IndexedDB, אבל ביצוע הפעולה הזו אחרי כל שינוי (גם אם היא מבוצעת עם בקרת קצב או דחייה של הקלט) יוביל לחסימה מיותרת של הליבה הראשית, יגביר את הסבירות לשגיאות כתיבה ובמקרים מסוימים יוביל אפילו לקריסה של הכרטיסייה בדפדפן או לכך שהיא לא תגיב.
במקום לאחסן את כל עץ המצבים ברשומה אחת, כדאי לפצל אותו לרשומות נפרדות ולעדכן רק את הרשומות שבאמת משתנות.
כמו רוב השיטות המומלצות, זה לא כלל של 'הכול או כלום'. במקרים שבהם לא ניתן לפצל אובייקט מצב ולכתוב רק את קבוצת השינויים המינימלית, עדיין עדיף לפצל את הנתונים לעצי משנה ולכתוב רק אותם, במקום לכתוב תמיד את עץ המצב כולו. שיפורים קטנים טובים יותר משום שיפור בכלל.
לבסוף, תמיד צריך למדוד את ההשפעה על הביצועים של הקוד שאתם כותבים. אמנם נכון שכתיבה קטנה ב-IndexedDB תביא לביצועים טובים יותר מכתיבה גדולה, אבל זה חשוב רק אם הכתיבה ב-IndexedDB שהאפליקציה מבצעת מובילה למשימות ארוכות שסותמות את הליבה ומפחיתות את חוויית המשתמש. חשוב למדוד את הביצועים כדי להבין למה אתם מבצעים אופטימיזציה.
מסקנות
מפתחים יכולים להשתמש במנגנוני אחסון של לקוחות כמו IndexedDB כדי לשפר את חוויית המשתמש באפליקציה שלהם. הם יכולים לעשות זאת לא רק על ידי שמירת המצב במהלך סשנים, אלא גם על ידי קיצור הזמן הנדרש לטעינת המצב הראשוני בביקור חוזר.
שימוש נכון ב-IndexedDB יכול לשפר באופן משמעותי את חוויית המשתמש, אבל שימוש שגוי או אי-טיפול במקרים של שגיאות עלולים להוביל לאפליקציות לא תקינות ולמשתמשים לא מרוצים.
מכיוון ששמירת נתונים בלקוח כוללת גורמים רבים שאינם בשליטתכם, חשוב מאוד לבדוק היטב את הקוד ולטפל כראוי בשגיאות, גם כאלה שנראות בהתחלה לא סבירות.