يمكن أن تؤثّر طريقة إدارة التسلسل الهرمي لعناصر
View
بشكل كبير في
أداء تطبيقك. وتصف هذه الصفحة كيفية تقييم ما إذا كان التسلسل الهرمي لطريقة العرض
يبطئ من معدّل عمل التطبيق، وتقدّم بعض الاستراتيجيات لمعالجة المشاكل التي قد تنشأ.
تركّز هذه الصفحة على تحسين التنسيقات المستندة إلى View
. للحصول على معلومات عن تحسين
أداء Jetpack Compose، يُرجى الاطّلاع على مقالة أداء
Jetpack Compose.
قياس الأداء وتحديد التنسيق
تتضمّن مسار العرض مرحلة التنسيق والقياس، وخلالها يضع النظام
العناصر ذات الصلة في موضع مناسب في التدرّج الهرمي للعرض. يحدّد جزء القياس من هذه
المرحلة أحجام عناصر View
وحدودها. يحدِّد جزء التنسيق
موضع عناصر View
على الشاشة.
تُكلّف كلتا مرحلتَي مسار الإحالة الناجحة بعض التكلفة الصغيرة لكلّ مرّة عرض أو تنسيق تتم معالجتهما. في معظم
الأحيان، تكون هذه التكلفة ضئيلة ولا تؤثّر بشكل ملحوظ في الأداء. ومع ذلك، يمكن أن يكون حجمها أكبر
عندما يضيف تطبيق View
عنصرًا أو يزيل View
عنصرًا، مثل
RecyclerView
إعادة تدوير View
عنصر أو إعادة استخدامه. يمكن أن تكون التكلفة أيضًا أعلى إذا كان عنصر View
يحتاج
إلى إعادة ضبط حجمه لاستيفاء القيود المفروضة عليه. على سبيل المثال، إذا كان تطبيقك يستدعي SetText()
على كائن View
يلتف النص، قد تحتاج إلى تغيير حجم View
.
وإذا استغرقت مثل هذه الحالات وقتًا طويلاً، يمكن أن تمنع عرض الإطار خلال المدة المسموح بها عن 16 ملي ثانية، ما قد يؤدي إلى انخفاض عدد اللقطات وجعل الصور المتحركة رديئة.
وبما أنّه لا يمكنك نقل هذه العمليات إلى سلسلة مهام فرعية، يجب أن يعالجها تطبيقك على السلسلة الرئيسية، لذا من الأفضل تحسينها لكي تستغرق أقل وقت ممكن.
إدارة التنسيقات المعقّدة
تتيح لك تصاميم Android تداخل عناصر واجهة المستخدم في الهيكل الهرمي لطريقة العرض. ويمكن أن يؤدي هذا التداخل أيضًا إلى فرض تكلفة تنسيق. عندما يعالج تطبيقك كائنًا للتخطيط، ينفذ التطبيق أيضًا نفس العملية على جميع عناصر التخطيط.
في ما يتعلّق بالتنسيقات المعقّدة، لا تظهر تكلفة أحيانًا إلا في المرة الأولى التي يحسب فيها النظام التنسيق. على سبيل المثال، عندما يعيد تطبيقك تدوير عنصر قائمة معقّد في RecyclerView
كائن، يحتاج النظام إلى ترتيب جميع الكائنات. في مثال آخر، يمكن أن تنتشر التغييرات البسيطة
في أعلى السلسلة باتجاه العنصر الرئيسي إلى أن تصل إلى عنصر لا يؤثر في حجم
العنصر الرئيسي.
من الأسباب الشائعة لطول مدة التصميم هي تداخل التسلسلات الهرميّة لعناصر View
مع بعضها. يضيف كل كائن تخطيط متداخل تكلفة إلى مرحلة التصميم. كلما كان التسلسل الهرمي
أكثر تسطيحًا، قلّ الوقت الذي تستغرقه مرحلة التنسيق لإكمالها.
ننصح باستخدام
أداة تعديل التنسيق لإنشاء
ConstraintLayout
بدلاً من
RelativeLayout
أو
LinearLayout
لأنّها أكثر فعالية بشكل عام وتقلل من تداخل التنسيقات. ومع ذلك، لإنشاء تنسيقات بسيطة يمكن تنفيذها باستخدام FrameLayout
، ننصح باستخدام FrameLayout
.
إذا كنت تستخدِم فئة RelativeLayout
، قد تتمكّن من تحقيق أثره نفسه
بتكلفة أقل باستخدام مشاهدات LinearLayout
متداخلة غير مرجحة بدلاً من ذلك. ومع ذلك،
إذا كنت تستخدِم طرق عرض LinearLayout
متداخلة ومُثبَّتة الوزن، تكون تكلفة التنسيق أعلى بكثير
لأنّها تتطلّب عدّة مرّات تنسيق، كما هو موضّح في القسم التالي.
ننصح أيضًا باستخدام السمة RecyclerView
بدلاً من السمة ListView
، لأنّها تتيح إعادة تدوير تنسيقات عناصر القائمة الفردية، ما يجعلها أكثر كفاءة ويحسّن أداء التمرير.
الضريبة المزدوجة
عادةً ما ينفذ إطار العمل التخطيط أو مرحلة القياس في تمريرة واحدة. ومع ذلك، في بعض حالات التخطيط المعقدة، قد يضطر إطار العمل إلى التكرار عدة مرات على أجزاء من التسلسل الهرمي تتطلب تمريرات متعددة لحلها قبل وضع العناصر في النهاية. ويُشار إلى ضرورة إجراء أكثر من تكرار واحد للتنسيق والقياس باسم الضريبة المزدوجة.
على سبيل المثال، عند استخدام حاوية RelativeLayout
التي تتيح لك تحديد موضع
عناصر View
بالنسبة إلى مواضع عناصر View
أخرى، يؤدي
الإطار العمل التسلسل التالي:
- تنفيذ عملية وضع وقياس، يتم خلالها احتساب إطار العمل لمكان كل عنصر فرعي وحجمه، استنادًا إلى طلب كل طفل.
- يتم استخدام هذه البيانات، مع أخذ أوزان العناصر في الاعتبار، لتحديد الموضع المناسب للاطِّلاعات المرتبطة.
- ينفذ تمريرة تخطيط ثانية لإنهاء مواضع الكائنات.
- الانتقال إلى المرحلة التالية من عملية التقديم
وكلما زاد عدد المستويات في التسلسل الهرمي للعرض، زاد احتمال فرض عقوبة على الأداء.
كما ذكرنا سابقًا، يكون ConstraintLayout
بشكل عام أكثر فعالية من التنسيقات
الأخرى باستثناء FrameLayout
. وهي أقل عرضة لإجراء عدّة عمليات تنسيق، وفي العديد من
الحالات، تزيل الحاجة إلى تداخل التنسيقات.
قد تؤدي الحاويات غير RelativeLayout
أيضًا إلى زيادة الضرائب المزدوجة. على سبيل المثال:
- يمكن أن تؤدي طريقة العرض
LinearLayout
إلى إجراء تمريرة مزدوجة للتخطيط والقياس إذا غيّرت وضعها ليصبح عموديًا. قد يحدث أيضًا مرور مزدوج للتخطيط والقياس في الاتجاه العمودي إذا أضفتmeasureWithLargestChild
، وفي هذه الحالة قد يحتاج إطار العمل إلى إجراء مرور ثانٍ لتحديد الأحجام المناسبة للكائنات. - يسمح
GridLayout
أيضًا بتحديد موضع نسبي، ولكنّه عادةً ما يتجنب فرض رسوم مزدوجة من خلال المعالجة المسبقة للعلاقات الموضعية بين طرق العرض الفرعية. ومع ذلك، إذا كان التنسيق يستخدم الأوزان أو التعبئة مع فئةGravity
، ستفقد ميزة المعالجة المسبقة ، وقد يحتاج إطار العمل إلى إجراء عدة مرّات إذا كانت الحاوية هيRelativeLayout
.
لا تؤدي عمليات المرور المتعددة للتخطيط والقياس بالضرورة إلى خفض الأداء. ومع ذلك، يمكن أن تصبح عبئًا إذا كانت في المكان الخطأ. انتبه إلى الحالات التي ينطبق فيها أحد الشروط التالية على حاويتك:
- وهو عنصر جذر في التسلسل الهرمي للعرض.
- ويتضمن تسلسلاً هرميًا للعرض المعمّق أسفله.
- هناك العديد من الحالات التي تم فيها ملء الشاشة بالعناصر، مثل الأطفال في عنصر
ListView
.
تشخيص مشاكل هيكلية طرق العرض
يُعدّ أداء التنسيق مشكلة معقّدة لها العديد من الجوانب. يمكن أن تساعدك الأدوات التالية في تحديد نقاط الاختناق في الأداء. توفّر بعض الأدوات معلومات أقل دقة، ولكنها يمكن أن تقدّم لك نصائح مفيدة.
Perfetto
Perfetto هي أداة تقدّم بيانات عن الأداء. يمكنك فتح عمليات تتبُّع Android في واجهة مستخدم Perfetto.
رسم مخطط لعرض GPU
يمكن أن تقدّم لك أداة عرض وحدة معالجة الرسومات في الملف الشخصي المتوفّرة على الأجهزة التي تعمل بالإصدار 6.0 من Android (المستوى 23 من واجهة برمجة التطبيقات) والإصدارات الأحدث، معلومات محدّدة حول نقاط الاختناق في الأداء. تتيح لك هذه الأداة معرفة المدة التي تستغرقها مرحلة التصميم والقياس لكل إطار من المعالجة. يمكن أن تساعدك هذه البيانات في تشخيص مشاكل الأداء أثناء التشغيل ومساعدتك في تحديد المشاكل المتعلّقة بالتنسيق والقياس التي تحتاج إلى معالجتها.
في التمثيل الرسومي للبيانات التي تلتقطها، يستخدم عرض وحدة معالجة الرسومات في الملف الشخصي اللون الأزرق لتمثيل وقت التخطيط. لمزيد من المعلومات حول كيفية استخدام هذه الأداة، يُرجى الاطّلاع على مقالة سرعة عرض وحدة معالجة الرسومات في الملف الشخصي.
Lint
يمكن أن تساعدك أداة Lint في Android Studio في التعرّف على المشاكل في التسلسل الهرمي للعرض. لاستخدام هذه الأداة، اختَر تحليل > فحص الرمز، كما هو موضح في الشكل 1.
تظهر معلومات عن عناصر التنسيق المختلفة ضمن Android > Lint > الأداء. للاطّلاع على مزيد من التفاصيل، انقر على كل عنصر لتوسيعه وعرض مزيد من المعلومات في اللوحة على جانب اليمين من الشاشة. يوضح الشكل 2 مثالاً لمعلومات موسّعة.
يؤدي النقر على عنصر إلى عرض المشاكل المرتبطة به في اللوحة على يسار الصفحة.
للحصول على مزيد من المعلومات حول المواضيع والمشاكل المحددة في هذا المجال، يمكنك الاطّلاع على مستندات Lin.
أداة فحص التنسيق
توفّر أداة مُدقّق التنسيق في Android Studio تمثيلًا مرئيًا للتسلسل الهرمي لعرض تطبيقك. إنها طريقة جيدة للتنقل في التسلسل الهرمي لتطبيقك، وتوفر تمثيلاً مرئيًا واضحًا للسلسلة الرئيسية لطريقة عرض معينة، وتتيح لك فحص التنسيقات التي يبنيها تطبيقك.
يمكن أن تساعد طرق العرض التي يقدمها Layout Inspector (أداة فحص التخطيط) أيضًا في تحديد مشكلات الأداء الناتجة عن الضرائب المزدوجة. يمكن أن يوفر لك أيضًا وسيلة لتحديد سلاسل عميقة من التخطيطات المتداخلة، أو تخطيط المناطق التي تحتوي على عدد كبير من العناصر الثانوية المتداخلة، والتي يمكن أن تكون مصدرًا لتكاليف الأداء. في هذه الحالات، يمكن أن تكون مرحلتا التخطيط والقياس مكلفة وتؤدي إلى حدوث مشكلات في الأداء.
لمزيد من المعلومات، يُرجى الاطّلاع على مقالة تصحيح أخطاء التنسيق باستخدام أداة "فحص التنسيق" و"التحقّق من التنسيق".
حلّ المشاكل المتعلّقة بهيكلية طرق العرض
يمكن أن يكون المفهوم الأساسي لحلّ مشاكل الأداء التي تنشأ من التسلسلات الهرميّة للعرض صعبًا في الممارسة. يتمثل منع التدرّجات الهرميّة للعروض من فرض عقوبات على الأداء في تسطيح التدرّج الهرمي للعرض والحدّ من فرض الضرائب مرتين. يناقش هذا القسم استراتيجيات لتحقيق هذه الأهداف.
إزالة التنسيقات المتداخلة المكررة
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
"، بالإضافة إلى المزيد من الميزات للمساعدة في
إنشاء تنسيقات أكثر تنظيمًا وفعالية.