تجنُّب عمليات التنزيل غير المحسَّنة

يواجه بعض مستخدمي تطبيقك صعوبة في الوصول إلى الإنترنت بشكل متقطع أو لديهم قيود على مقدار المعلومات التي يمكنهم تنزيلها على أجهزتهم. يمكنك تشجيع المستخدمين على التفاعل مع تطبيقك بشكل أكبر من خلال تقليل مقدار البيانات التي يحتاج تطبيقك إلى تنزيلها.

إنّ أبسط طريقة لتقليل عمليات التنزيل هي تنزيل المحتوى الذي تحتاجه فقط. من ناحية البيانات، يعني ذلك تنفيذ واجهات REST API التي تتيح لك تحديد معايير طلب البحث التي تحدّ من البيانات المعروضة باستخدام مَعلمات مثل وقت آخر تعديل.

وبالمثل، عند تنزيل الصور، من الأفضل تقليل حجم الصور من جهة الخادم بدلاً من تنزيل صور بالحجم الكامل ثم تقليل حجمها من جهة العميل.

تخزين استجابات HTTP مؤقتًا

من الأساليب المهمة الأخرى تجنُّب تنزيل بيانات مكرّرة. يمكنك تقليل احتمال تنزيل جزء البيانات نفسه بشكل متكرّر من خلال استخدام التخزين المؤقت. من خلال تخزين بيانات تطبيقك وموارده مؤقتًا، يمكنك إنشاء نسخة محلية من المعلومات التي يحتاج تطبيقك إلى الرجوع إليها. إذا كان تطبيقك يحتاج إلى الوصول إلى المعلومات نفسها عدة مرات خلال فترة زمنية قصيرة، عليك تنزيلها في ذاكرة التخزين المؤقت مرة واحدة فقط.

من المهم تخزين البيانات مؤقتًا بأكبر قدر ممكن من الفعالية لتقليل إجمالي حجم البيانات التي يتم تنزيلها. يجب دائمًا تخزين الموارد الثابتة مؤقتًا، بما في ذلك عمليات التنزيل عند الطلب، مثل الصور بالحجم الكامل، لأطول فترة ممكنة بشكل معقول. يجب تخزين الموارد عند الطلب بشكل منفصل لتتمكّن من إفراغ ذاكرة التخزين المؤقت عند الطلب بانتظام لإدارة حجمها.

لضمان ألا يؤدي التخزين المؤقت إلى عرض تطبيقك لبيانات قديمة، استخدِم رموز حالة 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. ويشمل ذلك إنشاء فئة مخصّصة تُعرف باسم "مستودع"، وتوفّر تجريدًا لواجهة برمجة التطبيقات (API) لبعض البيانات أو الموارد المحدّدة. قد يسترد المستودع بياناته في البداية من مصادر مختلفة، مثل خدمة ويب بعيدة، ولكنّه يوفّر للمتصلين نسخة مخزّنة مؤقتًا من البيانات في المكالمات اللاحقة. تتيح لك هذه الطبقة من التوجيه غير المباشر توفير استراتيجية تخزين مؤقت قوية خاصة بتطبيقك. لمزيد من المعلومات حول استخدام نمط المستودع في تطبيقك، راجِع دليل بنية التطبيق.