كيفية جمع التحليلات وعدم قتل الإنتاجية

يُعد Analytics جزءًا لا يتجزأ من تطبيق حديث للجوّال. يتيح لك Analytics جمع معلومات حول المستخدم من أجل تطوير المنتج وتحسينه.

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

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

المحاولة رقم 1


بعد أن تلقى المهمة لجمع التحليلات ، أظهر الفريق النتيجة بسرعة. كان الزناد لتوليد حدث طريقة onViewAttachedToWindow . يبدو أن كل شيء على ما يرام ، ولكن مع التمرير السريع ، تم تعليق الواجهة بشكل ملحوظ - حدث خطأ ما. يجب حل المشكلة.

يرى الجميع التعليق بشكل مختلف ، لذلك كنا بحاجة إلى الحقائق والأدلة. لقياس التأخر ، تم اختيار FPS (Frames Per Second) ، و TinyDenser بمقياس FPS لقياس التأخير . بعد توصيل الأداة ، تلقى الفريق تأكيدًا موضوعيًا للمشكلة - انخفض المؤشر ، وأحيانًا بشكل ملحوظ: أقل من 30 إطارًا في الثانية ، يظهر تسجيل الشاشة مع تشغيل الأداة في الشكل 1.

الصورة
الشكل 1. تسجيل الشاشة قبل التحسين

المحاولة رقم 2


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

class IdleStateScrollListener(private val analyticsFacade: AnalyticsFacade) : RecyclerView.OnScrollListener() { fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { analyticsFacade.setPending(newState != RecyclerView.SCROLL_STATE_IDLE) } } 

الخطوة التالية هي تنفيذ تراكم الأحداث وإرسالها.

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

هذا أدى إلى نتائج فورية ، زيادة كبيرة في FPS. من حيث المبدأ ، تم حل المشكلة ، في الشكل 2 نرى نتيجة التطبيق بعد المحاولة الثانية. ولكن لم يبق سوى مهمة واحدة - تم إرسال الأحداث إلى الخدمة ، مما أدى إلى التكاثر المتكرر للأشياء من فئة Intent ، وهذا أيضًا عبء على GC وقدم "وسائل الراحة" في شكل توقفات توقف العالم .

الصورة
الشكل 2. تسجيل الشاشة بعد المحاولة الثانية

المحاولة رقم 3


يعتقد الفريق: "ليس إرسال حدث واحد في كل مرة ، ولكن قائمة الأحداث هي فكرة رائعة أخرى". بعد تحسين قصير للفئة ، نفذ الفريق إرسال الأحداث حسب القائمة وتلقى قيمًا ثابتة للمؤشر عند مستوى 55-60 إطارًا في الثانية (الشكل 3).

الصورة

الشكل 3. تسجيل الشاشة بعد المحاولة الثالثة

الاستنتاجات


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

هل يمكن القيام بشيء آخر؟


استقر فريقنا على الخيار الثالث ، ولكن هذا ليس الشيء الوحيد الذي يمكن تطبيقه.

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

Source: https://habr.com/ru/post/ar414899/


All Articles