وضع التخطي القوي

"التخطّي القوي" هو وضع متوفّر في "مجمّع الإنشاء". عند تفعيل هذا الخيار، يؤدي ذلك إلى تغيير سلوك المُجمِّع بطريقتَين:

  • تصبح العناصر القابلة للتجميع التي تحتوي على مَعلمات غير ثابتة قابلة للتخطّي.
  • يتم تذكُّر وظائف Lambda التي تتضمّن عمليات تسجيل غير مستقرة.

تفعيل وضع التخطّي القوي

يتم تفعيل ميزة "التخطّي القوي" تلقائيًا في Kotlin 2.0.20.

لتفعيل ميزة "التخطّي القوي" لوحدة Gradle في إصدار أقدم من 2.0.20، أدرِج الخيار التالي في وحدة composeCompiler من إعدادات Gradle:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

إمكانية التخطّي القابلة للتجميع

يُخفِّف "وضع التخطّي القوي" بعض قواعد الثبات التي يطبّقها عادةً compilador Compose عند التخطّي والدوالّ القابلة للتركيب. بشكلٍ تلقائي، يضع مُجمِّع Compose علامة على الدالة القابلة للتجميع كقابلة للتخطّي إذا كانت كل مَعلماتها ذات قيم ثابتة. يغيّر وضع "التخطّي السريع" هذا الإعداد.

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

الحالات التي يجب فيها التخطّي

لتحديد ما إذا كان سيتم تخطّي عنصر قابل للتركيب أثناء إعادة التركيب، يقارن Compose قيمة كل مَعلمة بقيمها السابقة. يعتمد نوع المقارنة على ثبات المَعلمة.

  • تتم مقارنة المَعلمات غير المستقرة باستخدام مساواة العنصر (===).
  • تتم مقارنة المَعلمات الثابتة باستخدام تساوي الكائنات (Object.equals()).

إذا كانت جميع المَعلمات تستوفي هذه المتطلبات، يتخطّى Compose العنصر القابل للتركيب أثناء إعادة التركيب.

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

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

إضافة تعليقات توضيحية إلى الفئات على أنّها مستقرة

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

ميزة "تذكُّر الدوال البرمجية" في Lambda

يتيح وضع التخطي القوي أيضًا المزيد من تخزين المراجع للوظائف اللاتلامحية داخل العناصر القابلة للتجميع. عند تفعيل ميزة "التخطّي القوي"، سيتم تلقائيًا تذكُّر كل دالة LAMBDA داخل دالة قابلة للتجميع.

أمثلة

لتحقيق ميزة "تذكُّر" الدوالّ اللامدا داخل العناصر القابلة للتجميع عند استخدام ميزة "التخطّي القوي"، يلفّ المُجمِّع دالة اللامدا باستدعاء remember. ويتمّ استخدام ملف السجلّ مع عمليات تسجيل دالة lambda.

لنفترض أنّ لديك دالة lambda كما هو موضّح في المثال التالي:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

عند تفعيل ميزة "التخطّي القوي"، يحفظ المُجمِّع دالة LAMBDA في الذاكرة من خلال لفّها في طلب remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

تلتزم المفاتيح بقواعد المقارنة نفسها التي تلتزم بها الدوال القابلة للتجميع. تقارن بيئة التشغيل المفاتيح غير المستقرة باستخدام مساواة العنصر. ويقارن المفاتيح الثابتة باستخدام تكافؤ العناصر.

الحفظ المؤقت وإعادة التركيب

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

تجنَّب ميزة "تذكير".

إذا كان لديك دالة لا تريد الاحتفاظ بذاكرتها، استخدِم التعليق التوضيحي @DontMemoize.

val lambda = @DontMemoize {
    ...
}

حجم حزمة APK

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

أدّى تفعيل ميزة "التخطّي السريع" في ميزة الميزات المتوفّرة الآن في Android إلى زيادة حجم ملف APK بقيمة 4 كيلوبايت. يعتمد الفرق في الحجم إلى حد كبير على عدد العناصر القابلة للدمج التي كانت في السابق غير قابلة للتخطّي في التطبيق المحدّد، ولكن من المفترض أن يكون الاختلاف بسيطًا نسبيًا.