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

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

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

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

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

שמירה על תחזיות מפני האפליקציה

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

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

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

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

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

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

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

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

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

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

בדיקות יחידה (unit testing) יכולות להיות שימושיות מאוד, כי לעיתים קרובות לא ניתן לבדוק באופן ידני את כל התרחישים ונתיבי השדרוג האפשריים.

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

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

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

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

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

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

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

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

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

מסקנות

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

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

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