العروض الهرمية على الأداء والعرض

يمكن أن تؤثّر طريقة إدارة التسلسل الهرمي لعناصر View بشكل كبير في أداء تطبيقك. تصف هذه الصفحة كيفية تقييم ما إذا كان التسلسل الهرمي لطريقة العرض يبطئ تطبيقك، وتقدم بعض الاستراتيجيات لمعالجة المشكلات التي قد تحدث.

تركز هذه الصفحة على تحسين التنسيقات التي تستند إلى View. للحصول على معلومات عن تحسين أداء Jetpack Compose، يُرجى الاطّلاع على أداء Jetpack Compose.

التخطيط والقياس

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

تتكبد كل من مرحلتي المسارات هذه بعض التكلفة الصغيرة لكل مشاهدة أو تخطيط تتم معالجتهما. في معظم الأحيان، تكون هذه التكلفة ضئيلة ولا تؤثر بشكل ملحوظ على الأداء. ومع ذلك، يمكن زيادة عددها عندما يضيف أو يزيل أحد التطبيقات عناصر View، مثلاً عندما يعيد عنصر RecyclerView تدويرها أو يعيد استخدامها. يمكن أيضًا أن تكون التكلفة أعلى إذا احتاج عنصر View إلى تغيير حجمه لاستيفاء قيوده. على سبيل المثال، إذا استدعى تطبيقك SetText() على عنصر View الذي يلتف النص، قد يحتاج View إلى تغيير حجمه.

وإذا استغرقت مثل هذه الحالات وقتًا طويلاً جدًا، قد تمنع عرض إطار ضمن الحدود المسموح بها التي تبلغ 16 ملي ثانية، ما قد يؤدي إلى إسقاط الإطارات وجعلها رديئة.

ونظرًا لأنه لا يمكنك نقل هذه العمليات إلى سلسلة تعليمات للموظفين، يجب أن يعالجها التطبيق هذه العمليات في سلسلة التعليمات الرئيسية، فمن الأفضل تحسينها بحيث تستغرق أقل وقت ممكن.

إدارة التخطيطات المعقدة

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

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

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

ونقترح استخدام أداة تعديل التنسيق لإنشاء ConstraintLayout، بدلاً من RelativeLayout أو LinearLayout، لأنّه بشكل عام أكثر فعالية ويقلل من تداخل التنسيقات. مع ذلك، ننصحك باستخدام FrameLayout لإنشاء تنسيقات بسيطة يمكن تنفيذها باستخدام FrameLayout.

إذا كنت تستخدم الفئة RelativeLayout، قد تتمكّن من تحقيق التأثير نفسه بتكلفة أقل باستخدام طرق عرض LinearLayout المضمّنة وغير المُرجّحة بدلاً من ذلك. مع ذلك، إذا كنت تستخدم طرق عرض LinearLayout موزَّعة ومدمجة، ستكون تكلفة التنسيق أعلى بكثير، لأنها تتطلب بطاقات تخطيط متعددة، كما هو موضّح في القسم التالي.

نقترح أيضًا استخدام RecyclerView بدلاً من ListView، لأنّها تتيح إعادة تدوير تنسيقات عناصر القائمة الفردية، وهي أكثر فعالية ويمكن أن تحسِّن من أداء التمرير.

الضرائب المزدوجة

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

على سبيل المثال، عند استخدام حاوية RelativeLayout التي تتيح لك تحديد موضع كائنات View بالنسبة إلى مواضع كائنات View الأخرى، ينفّذ إطار العمل التسلسل التالي:

  1. تنفيذ تمريرة تخطيط وقياس، حيث يحسب إطار العمل موضع كل عنصر ثانوي وحجمه، استنادًا إلى طلب كل طفل.
  2. يستخدم هذا المقياس هذه البيانات، مع مراعاة ترجيحات العنصر، لتحديد الموضع المناسب لطرق العرض المرتبطة.
  3. يؤدي تمرير تخطيط ثانٍ لإنهاء مواضع الكائنات.
  4. الانتقال إلى المرحلة التالية من عملية العرض

وكلما زاد عدد مستويات العرض الهرمي، زادت احتمالية فرض عقوبة على الأداء.

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

وقد تؤدي الحاويات الأخرى غير RelativeLayout أيضًا إلى زيادة الضرائب المقتطعة. على سبيل المثال:

  • يمكن أن ينتج عن عرض LinearLayout تمريرة تنسيق ومقياس مزدوجة إذا جعلته أفقيًا. قد يتم أيضًا تنفيذ تمرير مزدوج في الاتجاه والقياس في الاتجاه العمودي في حال إضافة measureWithLargestChild، في هذه الحالة قد يحتاج إطار العمل إلى إجراء تمريرة ثانية لتعديل الأحجام المناسبة للعناصر.
  • تتيح السمة GridLayout أيضًا تحديد الموضع النسبي، ولكنّها عادةً ما تتجنّب ازدواج الضرائب من خلال المعالجة المسبقة لعلاقات الموضع بين المشاهدات الفرعية. ومع ذلك، إذا كان التنسيق يستخدم قيم ترجيح أو تعبئة بالفئة Gravity، ستفقد ميزة المعالجة المسبقة، وقد يكون على إطار العمل إجراء عدة تمريرات إذا كانت الحاوية هي RelativeLayout.

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

  • وهو عنصر جذر في العرض الهرمي لطريقة العرض.
  • ويشتمل على تسلسل هرمي عميق تحته.
  • هناك العديد من الحالات التي تملأ الشاشة فيها، تشبه العناصر الثانوية في عنصر ListView.

تشخيص مشاكل العرض الهرمي

فأداء التنسيق هو مشكلة معقدة تشتمل على عدة جوانب. يمكن أن تساعدك الأدوات التالية في تحديد مكان حدوث المؤثِّرات السلبية على الأداء. توفر بعض الأدوات معلومات أقل دقة ولكنها يمكن أن توفر تلميحات مفيدة.

بيرفيتو

Perfetto هي أداة توفّر بيانات حول الأداء. يمكنك فتح آثار أنشطة Android في واجهة مستخدم Perfetto.

رسم مخطط لعرض GPU

يمكن أن توفّر لك أداة عرض وحدة معالجة الرسومات الملف الشخصي على الجهاز فقط، والمتاحة على الأجهزة التي تعمل بنظام التشغيل Android 6.0 (مستوى واجهة برمجة التطبيقات 23) والإصدارات الأحدث، معلومات ملموسة حول المؤثِّرات السلبية في الأداء. تتيح لك هذه الأداة معرفة المدة التي تستغرقها مرحلة التنسيق والقياس لكل إطار عرض. يمكن أن تساعدك هذه البيانات في تشخيص مشكلات أداء وقت التشغيل وفي تحديد مشكلات التخطيط والقياس التي تحتاج إلى معالجتها.

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

لينت

يمكن أن تساعدك أداة Lint في "استوديو Android" في استيعاب نقاط القصور في التسلسل الهرمي لطريقة العرض. لاستخدام هذه الأداة، حدد تحليل > فحص الرمز، كما هو موضح في الشكل 1.

الشكل 1. اختَر فحص الرمز في "استوديو Android".

تظهر معلومات عن عناصر التنسيق المختلفة ضمن Android > Lint > الأداء. للاطّلاع على مزيد من التفاصيل، انقر على كل عنصر لتوسيعه وعرض مزيد من المعلومات في الجزء على الجانب الأيسر من الشاشة. يوضح الشكل 2 مثالاً للمعلومات الموسّعة.

الشكل 2. عرض معلومات حول مشاكل معيّنة تحدّدها أداة Lint.

يؤدي النقر على عنصر إلى الكشف عن المشكلات المرتبطة بهذا العنصر في الجزء على اليمين.

لفهم المزيد من المعلومات عن مواضيع ومشاكل محدّدة في هذا المجال، يمكنك مراجعة مستندات Lint.

أداة فحص التنسيق

توفّر أداة أداة فحص التنسيق في "استوديو Android" تمثيلاً مرئيًا للتسلسل الهرمي لطريقة العرض لتطبيقك. وهي طريقة جيدة للتنقل في التسلسل الهرمي لتطبيقك، حيث توفر تمثيلاً مرئيًا واضحًا للسلسلة الرئيسية لطريقة عرض معينة، وتتيح لك فحص التنسيقات التي ينشئها تطبيقك.

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

ولمزيد من المعلومات، يُرجى الاطّلاع على تصحيح أخطاء التنسيق باستخدام "أداة فحص التنسيق" و"التحقّق من صحة التنسيق".

حلّ المشاكل في التسلسل الهرمي لطريقة العرض

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

إزالة التنسيقات المتداخلة المكررة

ConstraintLayout هي مكتبة Jetpack تضم عددًا كبيرًا من الآليات المختلفة لتحديد موضع طرق العرض ضمن التنسيق. يقلل ذلك من الحاجة إلى دمج ConstaintLayout ويمكن أن يساعد في تبسيط العرض الهرمي للعرض. يكون من الأسهل عادةً دمج التسلسلات الهرمية باستخدام ConstraintLayout مقارنةً بأنواع التنسيقات الأخرى.

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

اعتماد خيار الدمج أو التضمين

من الأسباب الشائعة للتنسيقات المتداخلة المتكررة هي العلامة <include>. على سبيل المثال، يمكنك تعريف تخطيط قابل لإعادة الاستخدام على النحو التالي:

<LinearLayout>
    <!-- some stuff here -->
</LinearLayout>

يمكنك بعد ذلك إضافة العلامة <include> لإضافة العنصر التالي إلى الحاوية الرئيسية:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_bg"
    android:gravity="center_horizontal">

    <include layout="@layout/titlebar"/>

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:text="@string/hello"
              android:padding="10dp" />

    ...

</LinearLayout>

يتضمن السابق تضمين تضمين التخطيط الأول بشكل غير ضروري في التخطيط الثاني.

يمكن أن تساعد العلامة <merge> في منع حدوث هذه المشكلة. للحصول على معلومات عن هذه العلامة، يُرجى الاطّلاع على استخدام العلامة <merge>.

استخدام تخطيط أرخص

قد لا تتمكن من ضبط مخطط التخطيط الحالي بحيث لا يحتوي على تخطيطات مكررة. في بعض الحالات، قد يكون الحل الوحيد هو تسطيح التسلسل الهرمي عن طريق التبديل إلى نوع تخطيط مختلف تمامًا.

على سبيل المثال، قد تجد أنّ TableLayout يقدّم الوظيفة نفسها التي يوفّرها تصميم أكثر تعقيدًا مع العديد من تبعيات الموضع. توفّر مكتبة Jetpack ConstraintLayout وظائف مماثلة لميزات RelativeLayout، بالإضافة إلى المزيد من الميزات للمساعدة في إنشاء تصاميم أكثر جاذبية وفعالية.