طرق التنفيذ

اعتبارات أعمق بشأن الأداء

قراءة لمدة 8 دقائق
3 المؤلفون
Ben Weiss, Breana Tate, Jossi Wolf

استرخِ ودعنا نقدّم لك المزيد من المعلومات الأساسية حول الأداء.

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

التحسين الموجّه بالملف الشخصي

تُعدّ ملفات Baseline Profiles وملفات Startup Profiles أساسية لتحسين أداء بدء التشغيل وأداء وقت التشغيل لتطبيقات Android. وهي جزء من مجموعة تحسينات الأداء المعروفة باسم "التحسين المستند إلى الملف الشخصي".

عند إنشاء حِزمة تطبيق، يأخذ برنامج d8 dexer الفئات والطُرق ويملأ ملفات classes.dex في تطبيقك. عندما يفتح المستخدم التطبيق، يتم تحميل ملفات dex هذه واحدًا تلو الآخر إلى أن يتمكّن التطبيق من البدء. من خلال توفير ملف بدء التشغيل، يمكنك إعلام أداة d8 بالفئات والطرق التي يجب تضمينها في ملفات classes.dex الأولى. يتيح هذا البناء للتطبيق تحميل عدد أقل من الملفات، ما يؤدي بدوره إلى تحسين سرعة بدء التشغيل.

تنقل "ملفات تعريف الخط الأساس" خطوات التجميع أثناء التنفيذ (JIT) بشكل فعّال من أجهزة المستخدمين إلى أجهزة المطوّرين. وقد ثبت أنّ الرمز البرمجي الذي تم تجميعه مسبقًا (AOT) يقلّل من وقت بدء التشغيل ومشاكل العرض على حد سواء.

‫Trello وملفات Baseline Profile

سألنا المهندسين في تطبيق Trello عن تأثير "ملفات Baseline Profiles" في أداء التطبيق. بعد تطبيق "ملفات تعريف خط الأساس" على رحلة المستخدم الرئيسية، لاحظ فريق Trello انخفاضًا كبيرًا بنسبة % 25 في وقت بدء تشغيل التطبيق.

image.png

تمكّنت Trello من تحسين وقت بدء تشغيل تطبيقها بنسبة % 25 من خلال استخدام "ملفات تعريف المرجع".

ملفات Baseline Profile في Meta

نشر المهندسون في Meta مؤخرًا مقالة حول كيفية تسريع تطبيقات Android باستخدام "ملفات Baseline Profiles".

image.png

في تطبيقات Meta، لاحظت الفِرق تحسّنًا في مختلف المقاييس المهمة بنسبة تصل إلى % 40 بعد تطبيق "ملفات Baseline Profile".

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

بدء استخدام "ملفات Baseline"

لإنشاء ملف تعريف أساسي أو ملف تعريف بدء التشغيل، عليك كتابة اختبار Macrobenchmark يختبر التطبيق. أثناء الاختبار، يتم جمع بيانات ملف التعريف التي سيتم استخدامها أثناء تجميع التطبيق. تتم كتابة الاختبارات باستخدام UiAutomator API الجديد، وسنتناول هذا الموضوع غدًا.

إنّ كتابة مقياس أداء كهذا أمر بسيط، ويمكنك الاطّلاع على النموذج الكامل على GitHub.

  @Test

fun profileGenerator() {

    rule.collect(

        packageName = TARGET_PACKAGE,

        maxIterations = 15,

        stableIterations = 3,

        includeInStartupProfile = true

    ) {

        uiAutomator {

            startApp(TARGET_PACKAGE)

        }

    }


}

الاعتبارات

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

بدء استخدام ميزة "التحسين المستند إلى الملف الشخصي"

للتعرّف على طريقة عمل "ملفات تعريف خط الأساس"، شاهِد هذا الفيديو من "قمة مطوّري تطبيقات Android":

يمكنك أيضًا مشاهدة حلقة Android Build Time حول ميزة "التحسين المستند إلى الملف الشخصي" للحصول على نظرة متعمقة أخرى: 

يتوفّر أيضًا إرشادات شاملة حول ملفات Baseline Profiles وملفات Startup Profiles يمكنك الاطّلاع عليها.

تحسينات على أداء Jetpack Compose

لقد أثمر استثمار فريق الهندسة في أداء إطار عمل واجهة المستخدم لنظام التشغيل Android. فمنذ الإصدار 1.9 من Jetpack Compose، انخفض إيقاف مؤقت لعرض واجهة المستخدم أثناء التمرير إلى % 0.2 خلال اختبار داخلي لقياس الأداء للتمرير الطويل. 

jankyFrames.png

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

نافذة ذاكرة التخزين المؤقت القابلة للتخصيص

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

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

  val dpCacheWindow = LazyLayoutCacheWindow(ahead = 150.dp, behind = 100.dp)

val state = rememberLazyListState(cacheWindow = dpCacheWindow)

LazyColumn(state = state) {

    // column contents

}

تركيبة قابلة للإيقاف المؤقت

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

image.png

المزيد من تحسينات أداء Compose

في الإصدارَين 1.9 و1.10 من Compose، أجرى الفريق أيضًا العديد من التحسينات التي لا تبدو واضحة بعض الشيء.

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

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

من التحسينات الأخرى على الأداء استخدام القيم المخزّنة مؤقتًا عند مراقبة المواضع من خلال onPlaced().

جلب النص مسبقًا في الخلفية

بدءًا من الإصدار 1.9، تتيح Compose إمكانية الجلب المسبق للنص في سلسلة تعليمات في الخلفية. يتيح لك ذلك تسخين الذاكرة المؤقتة مسبقًا لتسريع تخطيط النص، وهو أمر مهم لأداء عرض التطبيق. أثناء التخطيط، يجب تمرير النص إلى إطار عمل Android حيث يتم ملء ذاكرة تخزين مؤقت للكلمات. يتم تنفيذ هذا الإجراء تلقائيًا في سلسلة Ui. يمكن أن يؤدي نقل عملية الجلب المسبق وتعبئة ذاكرة التخزين المؤقت للكلمات إلى سلسلة الخلفية إلى تسريع التنسيق، خاصةً للنصوص الأطول. لإجراء عملية الجلب المُسبَق في سلسلة محادثات في الخلفية، يمكنك تمرير منفِّذ مخصّص إلى أي عنصر قابل للإنشاء يستخدم BasicText في الخلفية من خلال تمرير LocalBackgroundTextMeasurementExecutor إلى CompositionLocalProvider على النحو التالي.

  val defaultTextMeasurementExecutor = Executors.newSingleThreadExecutor()

CompositionLocalProvider(

    LocalBackgroundTextMeasurementExecutor provides DefaultTextMeasurementExecutor

) {

    BasicText("Some text that should be measured on a background thread!")


}

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

اعتبارات أداء العمل في الخلفية

العمل في الخلفية هو جزء أساسي من العديد من التطبيقات. قد تستخدم مكتبات مثل WorkManager أو JobScheduler لتنفيذ مهام مثل:

  • تحميل أحداث تحليلية بشكل دوري
  • مزامنة البيانات بين خدمة خلفية وقاعدة بيانات
  • معالجة الوسائط (أي تغيير حجم الصور أو ضغطها)

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

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

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

أدوات تصحيح الأخطاء المحلية للعمل في الخلفية: السيناريوهات الشائعة

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

للمساعدة في ذلك، تتضمّن WorkManager العديد من الأدوات ذات الصلة التي تساعدك في تصحيح الأخطاء محليًا وتحسين الأداء (بعض هذه الأدوات تعمل أيضًا مع JobScheduler). في ما يلي بعض السيناريوهات الشائعة التي قد تواجهها عند استخدام WorkManager، وشرح للأدوات التي يمكنك استخدامها لتصحيح الأخطاء فيها.

تصحيح الأخطاء المتعلقة بعدم تنفيذ العمل المجدوَل

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

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

تتوفّر عدة أدوات لتصحيح الأخطاء في هذا السيناريو.

أداة فحص المهام في الخلفية

"أداة فحص المهام في الخلفية" هي أداة فعّالة مدمجة مباشرةً في "استوديو Android". ويوفّر تمثيلاً مرئيًا لجميع مهام WorkManager والحالات المرتبطة بها (قيد التشغيل، في قائمة الانتظار، تعذّر التنفيذ، تم التنفيذ بنجاح). 

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

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

image.png

عرض قائمة "أداة فحص المهام في الخلفية"

image.png

عرض "الرسم البياني" في "أداة فحص المهام في الخلفية"

adb shell dumpsys jobscheduler

يعرض هذا الأمر قائمة بجميع مهام JobScheduler النشطة (التي تتضمّن WorkManager Workers) بالإضافة إلى القيود المحدّدة والقيود التي يفرضها النظام. تعرض هذه الطريقة أيضًا سجلّ الوظائف. 

استخدِم هذا الخيار إذا كنت تريد طريقة مختلفة لعرض عملك المُجدوَل والقيود المرتبطة به. بالنسبة إلى إصدارات WorkManager الأقدم من WorkManager 2.10.0، ستعرض adb shell dumpsys jobscheduler قائمة بـ Workers بهذا الاسم:

  [package name]/androidx.work.impl.background.systemjob.SystemJobService

إذا كان تطبيقك يتضمّن العديد من العاملين، سيسمح لك التحديث إلى الإصدار 2.10.0 من WorkManager بالاطّلاع على أسماء العاملين والتمييز بينهم بسهولة:

  #WorkerName#@[package name]/androidx.work.impl.background.systemjob.SystemJobService

المزايا: يفيد هذا الأمر في معرفة ما إذا كانت هناك أي قيود مفروضة من النظام، وهي القيود التي لا يمكنك تحديدها باستخدام "أداة فحص المهام في الخلفية". على سبيل المثال، سيؤدي ذلك إلى عرض حزمة التطبيق الاحتياطية، ما قد يؤثر في الفترة الزمنية التي يتم فيها إكمال العمل المجدوَل.

تفعيل ميزة تسجيل معلومات تصحيح الأخطاء

يمكنك تفعيل التسجيل المخصّص للاطّلاع على سجلّات WorkManager المطوَّلة التي سيتم إرفاق WM— بها. 

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

WorkInfo.StopReason

إذا لاحظت أداءً غير متوقّع لعامل معيّن، يمكنك مراقبة سبب إيقاف العامل في محاولة التشغيل السابقة آليًا باستخدام WorkInfo.getStopReason

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

المزايا: يمكنك استخدام WorkInfo.StopReason لجمع بيانات ميدانية حول أداء العاملين لديك.

تصحيح الأخطاء في مدة قفل التنشيط الطويلة التي تم تحديدها في "مؤشرات Android الحيوية" والمرتبطة بـ WorkManager

تتضمّن "مؤشرات Android الحيوية" مقياسًا لعمليات قفل التنشيط الجزئي الزائدة عن الحد، والذي يوضّح عمليات قفل التنشيط التي تساهم في استنزاف البطارية. قد تتفاجأ بمعرفة أنّ تكتسب WorkManager أقفال التنشيط لتنفيذ المهام، وإذا تجاوزت أقفال التنشيط الحدّ الذي يحدّده Google Play، يمكن أن يؤثر ذلك في مدى ظهور تطبيقك. كيف يمكنك تصحيح الخطأ لمعرفة سبب طول مدة قفل التنشيط المرتبطة بعملك؟ يمكنك استخدام الأدوات التالية.

لوحة بيانات "مؤشرات Android الحيوية"

تأكَّد أولاً في لوحة بيانات قفل التنشيط المفرط في "مؤشرات Android الحيوية" من أنّ مدة قفل التنشيط الطويلة ناتجة عن WorkManager وليس عن منبّه أو قفل تنشيط آخر. يمكنك استخدام مستندات تحديد أقفال التنشيط التي أنشأتها واجهات برمجة تطبيقات أخرى لمعرفة أقفال التنشيط التي يتم الاحتفاظ بها بسبب WorkManager. 

Perfetto

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

ضمن مسار "حالة الجهاز: المهام"،  يمكنك الاطّلاع على أي مهام تم تنفيذها وأقفال التنشيط المرتبطة بها.

deviceState.png

قسم "حالة الجهاز" في Perfetto، يعرض تنفيذ CleanupWorker وBlurWorker

المراجع

راجِع صفحة تصحيح أخطاء WorkManager للحصول على نظرة عامة على طرق تصحيح الأخطاء المتاحة في السيناريوهات الأخرى التي قد تواجهها.

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

الخطوات التالية

تجاوزنا اليوم عملية تخفيض حجم الرموز واستكشفنا الطريقة التي يعرض بها كلّ من "وقت تشغيل Android" وJetpack Compose تطبيقك. سواء كان ذلك من خلال تجميع المسارات الحرجة مسبقًا باستخدام "الملف الشخصي للمرجع" أو تسهيل حالات التمرير باستخدام ميزات الإصدارَين الجديدَين 1.9 و1.10 من Compose، تركّز هذه الأدوات على تجربة تطبيقك. وتعمّقنا في أفضل الممارسات لتصحيح أخطاء العمل في الخلفية.

اسأل Android

سنستضيف جلسة طرح أسئلة (AMA) مباشرة حول الأداء يوم الجمعة. اطرح أسئلتك الآن باستخدام ‎ #AskAndroid واحصل على إجابات من الخبراء.

التحدّي

طلبنا منك يوم الاثنين تفعيل R8. اليوم، نطلب منك إنشاء ملف شخصي للمرجع واحد لتطبيقك.

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

بعد الحصول على هذه البيانات، شغِّل Macrobenchmark لمقارنة CompilationMode.None وCompilationMode.Partial.

شارِك التحسينات التي أجريتها على وقت بدء التشغيل على وسائل التواصل الاجتماعي باستخدام #optimizationEnabled.

المتابعة غدًا

لقد قلّصت حجم تطبيقك باستخدام R8 وحسّنت وقت التشغيل باستخدام ميزة "التحسين المستند إلى الملفات الشخصية". ولكن كيف يمكنك إثبات هذه النجاحات للأطراف المعنية؟ وكيف يمكنك رصد المشاكل قبل أن تؤثر في الإصدار العلني؟

انضم إلينا غدًا في اليوم الرابع: دليل تسوية الأداء، حيث سنوضّح بالتفصيل كيفية قياس مدى نجاحك، بدءًا من بيانات الاختبار الميداني في "مؤشرات Play الحيوية" وصولاً إلى التتبُّع المحلي الدقيق باستخدام Perfetto.

تأليف:

متابعة القراءة