הימנעות מהורדות לא אופטימליות

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

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

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

שמירת תגובות HTTP במטמון

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

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

כדי לוודא שהנתונים שמוצגים באפליקציה לא יהיו מיושנים בגלל שמירה במטמון, צריך להשתמש בקודי סטטוס של HTTP וכותרות מתאימים, כמו הכותרות ETag וLast-Modified. כך תוכלו לקבוע מתי התוכן המשויך צריך להתעדכן. לדוגמה:

Kotlin

// url represents the website containing the content to place into the cache.
val conn: HttpsURLConnection = url.openConnection() as HttpsURLConnection
val currentTime: Long = System.currentTimeMillis()
val lastModified: Long = conn.getHeaderFieldDate("Last-Modified", currentTime)

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified
}

Java

// url represents the website containing the content to place into the cache.
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
long currentTime = System.currentTimeMillis();
long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

// lastUpdateTime represents when the cache was last updated.
if (lastModified < lastUpdateTime) {
    // Skip update
} else {
    // Parse update
    lastUpdateTime = lastModified;
}

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

Kotlin

val cacheDir = Context.getCacheDir()
val cacheSize = 10L * 1024L * 1024L // 10 MiB
val client: OkHttpClient = OkHttpClient.Builder()
    .cache(Cache(cacheDir, cacheSize))
    .build()

Java

File cacheDir = Context.getCacheDir();
long cacheSize = 10L * 1024L * 1024L; // 10 MiB
OkHttpClient client = new OkHttpClient.Builder()
    .cache(new Cache(cacheDir, cacheSize))
    .build();

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

אפשר לשמור במטמון נתונים לא רגישים בספריית המטמון החיצונית הלא מנוהלת באמצעות Context.getExternalCacheDir(). אפשרות אחרת היא לשמור נתונים במטמון של האפליקציה המנוהלת והמאובטחת באמצעות Context.getCacheDir(). שימו לב: יכול להיות שהמטמון הפנימי הזה יימחק כשהמערכת תפעל עם נפח אחסון פנוי נמוך.

שימוש במאגר

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