تحسين الصور النقطية

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

استخدام مكتبات تحميل الصور

يمكنك تحسين كفاءة تطبيقك باستخدام مكتبات تحميل الصور مثل Coil (للمشاريع التي تستخدم Kotlin أولاً) أو Glide (لمشاريع Java). تقلّل هذه المكتبات من استخدام تطبيقك للذاكرة من خلال إجراءات مثل تخزين الصور مؤقتًا وتغيير حجم الرسومات عند الحاجة وإعادة استخدام كائنات الرسومات.

تغيير حجم الصور عند الاقتضاء

احرص على استخدام حجم الصورة المناسب لاحتياجاتك. على سبيل المثال، يجب ألا تحمّل أبدًا صورة كبيرة في صورة مصغّرة صغيرة. بدلاً من ذلك، استخدِم طريقة مثل inSampleSize لتحميل نسخة من الصورة تم تغيير حجمها.

تتولّى مكتبات تحميل الصور، مثل Coil وGlide، عملية تغيير الحجم هذه تلقائيًا بشكلٍ تلقائي. يمكنك ضبط استراتيجيات تقليل حجم العيّنات باستخدام ImageLoader (لـ Coil) أو DownsampleStrategy (لـ Glide).

توفير مواد عرض بديلة لأحجام الشاشات المختلفة

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

عدم تطبيق المساحة المتروكة مباشرةً

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

اختيار تنسيق البكسل المناسب

وازن بين الذاكرة والجودة من خلال اختيار تنسيق البكسل المناسب. استخدِم RGB_565 عندما لا تحتاج إلى الشفافية. يستخدم هذا التنسيق نصف ذاكرة التنسيق التلقائي ARGB_8888.

في Glide، يمكنك ضبط ذلك باستخدام DecodeFormat. في Coil، يمكنك استخدام السمة bitmapConfig.

استخدام المتجهات حيثما أمكن ذلك

بالنسبة إلى الصور المكوّنة من أشكال هندسية، يكون الرسم المتجهي أصغر بكثير من الصورة النقطية، ويتم تغيير حجمه بسلاسة لأي كثافة عرض. عندما يكون ذلك مناسبًا، استخدِم عناصر مثل ShapeDrawable لتمثيل الرسومات.

إصدار الصور النقطية وإعادة استخدامها متى أمكن ذلك

يمكن أن تشغل ملفات الرسومات الكبيرة مساحة كبيرة من الذاكرة. للحدّ من تأثيرها، عليك إصدار كائنات الرسومات أو إعادة استخدامها متى أمكن ذلك.

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

إذا كنت تدير الرسومات يدويًا، عليك إصدار الصور النقطية عند الانتهاء منها من خلال استدعاء Bitmap.recycle وإزالة مرجع Bitmap على الفور، بدلاً من الاعتماد على جمع البيانات غير الضرورية.

نصائح وحيل أخرى

يسرد هذا القسم بعض الطرق الأخرى لتحسين أداء تطبيقك عند التعامل مع الرسومات.

عدم تضمين صور كبيرة في ملف AAB أو APK

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

العثور على الصور النقطية الزائدة

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

عند استخدام ImageBitmap، استدعِ prepareToDraw قبل الرسم

عند استخدام ImageBitmap، لبدء عملية تحميل الملمس إلى وحدة معالجة الرسومات، استدعِ ImageBitmap#prepareToDraw() قبل رسمه فعليًا. يساعد ذلك وحدة معالجة الرسومات في إعداد الملمس وتحسين أداء عرض صورة على الشاشة. تجري معظم مكتبات تحميل الصور هذا التحسين تلقائيًا، ولكن إذا كنت تعمل بنفسك مع فئة ImageBitmap، عليك أخذ ذلك في الاعتبار.

ننصحك بتمرير Int DrawableRes أو عنوان URL كمعلَمات إلى العنصر القابل للإنشاء بدلاً من Painter

بسبب تعقيدات التعامل مع الصور (على سبيل المثال، سيكون كتابة دالة تساوي لـ Bitmaps مكلفًا من الناحية الحسابية)، لا يتم وضع علامة صريحة على واجهة برمجة التطبيقات Painter بأنّها مستقرة باستخدام التعليق التوضيحي @Stable. يمكن أن تؤدي الفئات غير المستقرة إلى عمليات إعادة إنشاء غير ضرورية لأنّ المحول البرمجي لا يمكنه بسهولة استنتاج ما إذا كانت البيانات قد تغيّرت.

لذلك، ننصحك بتمرير عنوان URL أو رقم تعريف مورد قابل للرسم كمعلَمات إلى الدالة المركّبة، بدلاً من تمرير Painter كمعلَمة.

// Prefer this:
@Composable
fun MyImage(url: String) {

}
// Over this:
@Composable
fun MyImage(painter: Painter) {

}