كيفية إنشاء مهندسي Instagram Direct لبنية واجهة مستخدم مستندة إلى الذكاء الاصطناعي باستخدام Jetpack Compose وخفض تكلفة الرموز المميّزة لكل جلسة وكيل بنسبة %33
مدّة القراءة: 11 دقيقة
تمت كتابة منشور المدوّنة هذا بالتعاون مع فريق Meta
Instagram Direct هي إحدى المساحات الأساسية على Instagram، وتتعامل مع مليارات الرسائل من المستخدمين يوميًا. على مدار سنوات من التكرار، استخرج الفريق كل تحسين دقيق ممكن من نظام Android View القديم. ومع ذلك، فإنّ صيانة وتوسيع واجهة قديمة محسّنة بشكل كبير يؤدي إلى تراكم ديون فنية وأعباء هندسية كبيرة، خاصةً مع تزايد اعتماد الفِرق على واجهات المستخدم التعريفية ومساعدي البرمجة بالذكاء الاصطناعي.
لم يقتصر اعتماد Jetpack Compose في ميزة Instagram Direct على تحديث واجهة المستخدم المعتادة. أنشأ الفريق قاعدة رموز برمجية لواجهة مستخدم مستندة إلى الذكاء الاصطناعي أصغر بنسبة %50 من عملية التنفيذ الأصلية، مع تحقيق انخفاض بنسبة %35 في وقت تنفيذ وكيل الذكاء الاصطناعي، وانخفاض بنسبة %32 في عمليات تبادل المهام بين المهندسين والوكلاء، وانخفاض بنسبة %33 في تكلفة الرموز المميّزة. بالتعاون الوثيق مع Google، اعتمد الفريق Jetpack Compose مع الحفاظ على مستوى أداء عالٍ. من خلال تحسينات الأداء، حسّنت Meta وGoogle أداة Compose ليس فقط لتطبيق Instagram، بل أيضًا لمنظومة مطوّري برامج Android المتكاملة الأوسع نطاقًا.
تحديث قاعدة الرموز البرمجية على نطاق واسع
أصبح الذكاء الاصطناعي سريعًا رفيقًا يوميًا للمهندسين في هذا المجال، وتطبيقه على قاعدة رموز برمجية واسعة النطاق مثل Instagram يحقّق مكاسب حقيقية في الإنتاجية. وضع فريق Instagram Direct هدفًا أكثر طموحًا. بدلاً من توجيه أدوات الذكاء الاصطناعي إلى الرموز البرمجية الحالية، أعاد الفريق تصميم قاعدة الرموز البرمجية وبنيتها لتكون متوافقة مع الذكاء الاصطناعي، ما ضاعف تأثير الذكاء الاصطناعي بشكل يتجاوز بكثير ما يمكن أن يحقّقه التعديل وحده.
اختار فريق Instagram Direct مجموعة أدوات Jetpack Compose كمكوّن رئيسي لإنشاء بنية واجهة مستخدم مستندة إلى الذكاء الاصطناعي. تضمن طبيعتها التعريفية أن يكون الرمز البرمجي موجزًا وقابلاً للتوقّع وأسهل من الناحية الهيكلية لنماذج الذكاء الاصطناعي في الاستدلال، مع تأثيرات جانبية أقل وحالة ضمنية أقل وحدود مكوّنات أكثر وضوحًا.
تطلّبت عملية نقل البيانات إلى Jetpack Compose تخطيطًا دقيقًا. يرسل مئات الملايين من الأشخاص رسائل على Instagram كل يوم، لذلك كان لا بد من أن تكون عملية النقل تدريجية وسلسة، مع عدم حدوث أي انقطاع في التجربة أثناء قيام الفريق بإعادة تصميم الأساس الذي يرتكز عليه. لتوضيح حجم التحدي: يمكن عرض مكوّنات واجهة المستخدم الفردية في أكثر من 160 تبديل حالة مختلف، وتتعامل شاشة محادثة واحدة مع أكثر من 200 نوع مختلف من الرسائل.
عند نقل قاعدة رموز برمجية بهذا الحجم إلى Compose، من السهل اختيار الطريقة الأسهل وتضمين مكوّنات واجهة مستخدم Compose داخل هيكلية طرق العرض الحالية. كخطوة تزايدية أثناء عملية نقل تدريجية، يُعدّ ذلك صالحًا تمامًا. ومع ذلك، على المدى الطويل، يمثّل دمج Compose داخل قاعدة رموز برمجية تستند إلى العرض تحديًا. غالبًا ما تختار أدوات الذكاء الاصطناعي المسار الأسهل. إذا مزجت بين الرموز البرمجية لواجهة المستخدم التعريفية والأمرية، من المرجّح أن يمزجها الذكاء الاصطناعي بشكل غير صحيح، ما يؤدي إلى ظهور أخطاء دقيقة وتراكم الديون التقنية وتراجع الأداء.
إنشاء بنية واجهة مستخدم مستندة إلى الذكاء الاصطناعي
على مستوى Instagram، لا يمكن تجنُّب درجة من التجريد المعماري، وهو ما يحافظ على إمكانية صيانة التطبيق مع نموه. لنفترض أنّ لدينا نمطًا شائعًا، حيث يتم تصميم كل نوع عنصر RecyclerView كصنف فرعي من صنف أساسي مخصّص RecyclerViewItem يعرض دوال الربط المعتادة لدورة الحياة، مثل onBind.
المثال الأول
class ChatItem( val features: FeatureFlagProvider ) : RecyclerViewItem<ComposeViewHolder, ChatUiState> { // Imperative context: // AI could often take the path of least resistance and generate a mutable // state here, dispatched outside the ChatUiState. This class survives // re-bindings and is shared across multiple items, ultimately leading to // unexpected, hard-to-reproduce bugs. var isPinned: Boolean = false override fun onBind(holder: ComposeViewHolder, uiState: ChatUiState) { // Imperative context val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature") // Declarative context holder.composeView.setContent { // Blending imperative and declarative contexts if (isPinnedChatsEnabled) { Button(onClick = { isPinned = !isPinned }) { Text(if (isPinned) "Unpin" else "Pin") } } ... } } }
في المقتطف أعلاه، تظهر مشكلتان. أولاً، تتم قراءة العلامة isPinnedChatsEnabled في الرمز الإلزامي ثم يتم تسجيلها داخل دالة lambda في Compose، وهو اقتران دقيق بين النماذج. ثانيًا، يتم استخدام isPinned كحقل قابل للتغيير في العنصر نفسه بدلاً من ChatUiState، لذا يظلّ RecyclerView قابلاً لإعادة الربط وإعادة التدوير في جميع الصفوف، ما يؤدي إلى تسرُّب البيانات وظهور أخطاء يصعب تكرارها.
حتى عندما يتم تنظيف الرمز من خلال منح العنصر دالة @Composable مخصصة، تظل المشاكل نفسها قائمة.
المثال الثاني
class ChatItem( val features: FeatureFlagProvider ) : ComposeRecyclerViewItem<ChatUiState> { // Imperative context val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature") var isPinned: Boolean = false // Declarative context @Composable override fun Content(uiState: ChatUiState) { // Blending imperative and declarative contexts if (isPinnedChatsEnabled) { Button(onClick = { isPinned = !isPinned }) { Text(if (isPinned) "Unpin" else "Pin") } } ... } }
هذا مثال بسيط، لكنه يوضح مشكلة أوسع نطاقًا - فكلما قل عدد الحدود التي يتم منحها للذكاء الاصطناعي، انخفضت جودة الكود الذي ينتجه بمرور الوقت. تساعد الإجراءات الوقائية والمهارات، ولكنّها ليست كافية بمفردها، لأنّه عندما يواجه الذكاء الاصطناعي عوائق، غالبًا ما يتجاوزها لإزالة الحظر عن نفسه.
لجعل قاعدة الرموز البرمجية متوافقة مع الذكاء الاصطناعي، يجب اتّباع قاعدتَين عمليتَين:
- قلِّل الاعتماد على السياق المخصّص. كلما زادت المعرفة المخصّصة والمتعلّقة بقاعدة الرموز البرمجية التي يحتاجها وكيل الذكاء الاصطناعي لإجراء تغيير صحيح، انخفضت جودة نتائجه. وكلما كانت قاعدة الرموز البرمجية أقرب إلى أفضل الممارسات المعروفة، كانت نتائج الذكاء الاصطناعي أفضل.
- يجب أن تفرض قاعدة الرموز البرمجية المستندة إلى الذكاء الاصطناعي حدودها الخاصة. إنّ سدّ الثغرات في التصميم باستخدام مهارات الذكاء الاصطناعي لا يمكن توسيع نطاقه، لأنّ كل مهارة يتم تحميلها في السياق تستهلك رموزًا مميّزة ويمكن أن تؤدي إلى تراجع أداء الوكيل. بدلاً من ذلك، يجب أن تتحمل البنية نفسها هذا العبء. يتّبع وكلاء الذكاء الاصطناعي بطبيعتهم المسار الأسهل، لذا يجب أن يؤدي هذا المسار إلى إنشاء رمز برمجي صحيح وعالي الجودة، مع جعل قرارات التصميم السيئة صعبة ومكلفة.
لا يزال من الممكن تمثيل عنصر القائمة من خلال تجريده الخاص، ولكن في هذه الحالة، يتوفّر كل رمز Compose في الدالة الإنشائية، وبالتالي لا يمكنه الوصول إلى أعضاء الفئة أو الحالة، ومصدر الوسيطات الوحيد هو الدالة الإنشائية. وهذا يجعلها مكافئة لدالة @Composable عادية، مع التوافق مع البنية الحالية.
المثال الثالث
class ChatItem( val features: FeatureFlagProvider, val onPin: (Boolean) -> Unit, ) : ComposeItem<ChatUiState>( // Compose UI content = { uiState: ChatUiState -> val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature") if (isPinnedChatsEnabled) { Button(onClick = { onPin(!uiState.isPinned) }) { Text(if (uiState.isPinned) "Unpin" else "Pin") } } ... }, )
إنّ نقل قاعدة رموز برمجية بهذا الحجم هو مهمة ضخمة. لفترة طويلة، كان على مئات مكوّنات واجهة المستخدم التي تشكّل غالبية واجهة Direct UI أن تتعايش مع نظيراتها القديمة، مع الحفاظ على كليهما بالتوازي. وقد ساعدت عمليات سير العمل المستندة إلى الذكاء الاصطناعي في إتاحة عملية النقل الموازية هذه من خلال تسريع عملية كتابة كميات هائلة من الرموز البرمجية. هذا النهج هو ما سمح لفريق Direct بإجراء عملية النقل في وقت قياسي، كل ذلك بدون تعطيل بقية أعضاء الفريق، الذين واصلوا طرح الميزات التي تحسّن تجربة ملايين الأشخاص كل يوم.
شغّل العديد من المهندسين وكلاء الذكاء الاصطناعي الخاصين بهم في قاعدة معرفية مشتركة من المهارات والاتفاقيات القابلة لإعادة الاستخدام التي تم إنشاؤها أثناء عملية نقل البيانات. وقد ساعد ذلك في الحفاظ على اتساق سير العمل وأفضل الممارسات في الفريق، بدلاً من أن يكتشفها كل مهندس من جديد. في كل مساحة عرض، نفّذ الفريق عملية نقل البيانات على المراحل التالية:
- اكتب كل الرموز البرمجية في Compose باستخدام الذكاء الاصطناعي.
- وقد عملنا على تحسينه ومعالجة الحالات الاستثنائية وسدّ الثغرات في الأداء، إلى أن تم طرح واجهة المستخدم للمستخدمين الفعليين في اختبار علني.
يتيح تقسيم العمل إلى مرحلتَين لكل شاشة لمهندس واحد التنقّل بسرعة في جميع أنحاء الواجهة، وتسوية البنية والحالات الاستثنائية الصعبة مسبقًا. بعد وضع هذه الأساسيات، يمكن للآخرين التركيز على تجهيز واجهة المستخدم للإنتاج بدون التوقف لاتخاذ هذه القرارات الفنية بأنفسهم، ما يحافظ على سرعة عملية النقل بشكل عام.
وقد أثبتت نتائج عملية نقل البيانات صحة هذا النهج. بالنسبة إلى مساحات العرض التي تم نقلها في Instagram Direct، سمحت أداة Jetpack Compose للفريق بتقليل إجمالي مقدار رمز واجهة المستخدم بنسبة %50. كلما قلّت الرموز البرمجية التي ينشئها الذكاء الاصطناعي، زادت جودة النتائج وانخفضت تكلفة الرموز المميّزة لكل مهمة.
أجرينا تحليلاً داخليًا لبيانات قاعدة الرموز البرمجية لنظام Android في Instagram Direct، وقارنّا بين جلسات وكيل الذكاء الاصطناعي التي تعمل على Compose UI والمهام نفسها التي تستخدم Android Views. كانت مكاسب الكفاءة واضحة على مستوى بُعدَين:
- لكل حرف من الرموز البرمجية التي تم إنشاؤها: تطلّب استخدام Compose انخفاضًا بنسبة %32 في عمليات التبادل بين المهندسين والوكلاء وانخفاضًا بنسبة %35 في وقت تنفيذ الوكيل (الوقت المنقضي من بدء الوكيل العمل على طلب المهندس حتى عرض الردّ).
- لكل جلسة وكيل: انخفضت تكلفة الرموز المميّزة الإجمالية بنسبة %33 باستخدام Compose مقارنةً بـ Views.
نقدّم تقارير عن كفاءة المخرجات وأرقام الجلسات العادية لأنّها نتائج مفيدة بشكل مستقل. تقارن أرقام التبادلات بين المهندس والوكيل وأوقات التنفيذ استخدام الموارد لكل وحدة من المخرجات النهائية، بينما يقارن رقم الرموز المميزة التكلفة الإجمالية لجلسة وكيل نموذجية.
وكشفت البيانات أيضًا عن اختلاف ثابت في كيفية تعامل إطارَي العمل مع الرموز البرمجية المعقّدة أو الهشّة. تتتبّع Meta ذلك باستخدام نتيجة مخاطر تغييرات الرموز البرمجية، والتي تقيّم جودة الرموز البرمجية بشكل عام واحتمالية أن يؤدي التغيير إلى حدوث مشاكل في الإنتاج. وقد قاس التحليل كفاءة الموارد لدى الوكيل باستخدام مجموعة من استهلاك الرموز المميّزة ووقت تنفيذ الوكيل وتفاعلات المهندس مع الوكيل. ومع تراكم الملفات التي تسجّل درجة خطورة أعلى، تصبح جلسات وكيل الذكاء الاصطناعي أقل كفاءة في استخدام الموارد.
عندما يتضاعف مجموع نقاط المخاطر لملف معيّن، فإنّ واجهة المستخدم التي تم تنفيذها باستخدام طرق عرض Android تقلّل من كفاءة موارد الوكيل بنسبة %30 (لكل حرف يتم عرضه). في الظروف نفسها، يبلغ الانخفاض في واجهة مستخدم Jetpack Compose 9% فقط
من خلال الشراكة بين Google وMeta، قدّم فريق Instagram Direct منظورًا جديدًا لاعتماد Compose، حيث تعامل معه من خلال عدسة استعداد قاعدة الرموز البرمجية للذكاء الاصطناعي، وليس مجرد إعادة كتابة واجهة المستخدم. أظهر هذا العمل قوة Compose كأساس لبناء قواعد رموز برمجية وبُنى تعتمد على الذكاء الاصطناعي أولاً، خاصةً عند تطبيقها على نطاق تطبيقات مثل Instagram.
تحسينات الأداء
تُعدّ ميزة Instagram Direct من أهم ميزات التطبيق، ويتوقّع المستخدمون أن تكون سريعة ومتجاوبة في جميع الأوقات. كان اعتماد Jetpack Compose يعني فعليًا إعادة كتابة واجهة المستخدم بشكل كبير، وكان الهدف الأول هو الحفاظ على تجربة عالية الجودة بدون أي تراجعات.
لقد أدت سنوات من التكرار إلى رفع مستوى أداء التنفيذ القديم المستند إلى العرض على Instagram إلى مستوى عالٍ بشكل استثنائي، وكان الفريق بحاجة إلى تلبية هذا المعيار نفسه أثناء الانتقال إلى إطار عمل جديد تمامًا لواجهة المستخدم.
يقيس Instagram مئات، إن لم يكن آلاف، مقاييس الأداء. بالنسبة إلى استخدام Compose، كانت النقاط الثلاث التالية هي الأكثر أهمية:
- سرعة الاستعداد للتفاعل: مقدار الوقت بين فتح الشاشة والقدرة على استخدامها.
- الوقت المستغرَق للتحميل بالكامل : مقدار الوقت بين فتح الشاشة ووقت تحميل كل المحتوى بالكامل (مثل الصور).
- أداء الانتقال للأعلى أو للأسفل: يشير إلى مدى سلاسة الانتقال للأعلى أو للأسفل على الشاشة، بدون فقدان أي لقطات.
يتم تتبُّع هذه المقاييس في وقت التشغيل في مرحلة الإنتاج، ما يتيح إجراء اختبارات A/B لمقارنة واجهة مستخدم Compose التي تم نقلها مع واجهة المستخدم القديمة وتقييم تأثير هذا الجهد في الأداء.
من الطرق الشائعة لإجراء عملية نقل مثل هذه هي البدء على نطاق صغير، من خلال نقل عدد قليل من مكوّنات واجهة المستخدم، وجمع البيانات، ودراسة سلوكها. على الرغم من أنّ هذه النتائج الأولية مفيدة، إلا أنّها لا تقدّم سوى صورة جزئية، ما يؤدي إلى نتائج سلبية خاطئة في ما يتعلّق باعتماد Compose للأسباب التالية:
- غير ممثّل: يمكن أن يوفّر أحد مكوّنات واجهة المستخدم التي تم نقلها بيانات مفيدة حول أدائه العام على شاشة معيّنة. ومع ذلك، تختلف طريقة عمل المكوّنات المختلفة لأسباب لا يمكن تعميمها، لذا لا يمكنك دائمًا استقراء النتائج منها.
- تكلفة التشغيل التفاعلي: يدفع جزء صغير من Compose داخل قاعدة رموز برمجية كبيرة في View تكلفة ربط غير متوقعة بين النظامَين. يؤدي هذا العبء إلى تشويه القياس، لذا فإنّ النتائج المبكرة على نطاق صغير لا تعكس الشكل الفعلي لعملية نقل البيانات الكاملة.
ونتيجةً لذلك، فإنّ عمليات النقل الصغيرة، على الرغم من فائدتها، لا تعكس دائمًا التأثير الكامل لـ Compose. كلما زاد عدد الواجهات التي يتم نقلها بالكامل بدون انقطاعات في الربط، أصبحت الصورة أوضح وأفضل من حيث الأداء.
تم إنشاء الشاشات الأساسية في Instagram Direct حول قوائم طويلة من أنواع العناصر المتنوعة، والتي تم تنفيذها في الأصل باستخدام RecyclerView. تعتمد البنية على تجريدات مخصّصة لضمان قابلية التوسّع، ولكنّها تظل مرتبطة بدورة حياة النظام المستند إلى العرض.
كانت المهمة الأساسية للفريق هي نقل مئات العناصر الفردية في القائمة تدريجيًا إلى Compose ضمن البنية الحالية المستندة إلى RecyclerView، وطرحها في مرحلة الإنتاج ضمن مجموعات صغيرة مستقلة في إطار اختبارات A/B، وكل ذلك بدون إجراء تغييرات مرئية على تجربة المراسلة للمستخدم.
أكبر عيب في هذا الإعداد هو الاعتماد الكبير على نظام View القديم من خلال بنية RecyclerView أساسية، حتى بعد نقل كل عنصر في القائمة بالكامل إلى Compose. كخطوة تالية طبيعية، قرّر الفريق الاستثمار في استبدال البنية الأساسية المستندة إلى RecyclerView بالبديل الأصلي في Compose، وهو LazyColumn.
وهذا يعني أنّه يجب فصل مكوّنات واجهة مستخدم Compose عن إطار العمل الذي تم تضمينها فيه مع الحفاظ على توافقها مع كل من RecyclerView وLazyColumn في الوقت نفسه. من المهم أيضًا إمكانية التبديل بين الاثنين أثناء التشغيل من خلال علامات الميزات، لتفعيل اختبارات A/B.
على الرغم من أنّ عناصر Compose الجديدة متوافقة بشكل أساسي مع LazyColumn ويمكن توصيلها بشجرة إنشاء غير منقطعة، تم إنشاء واجهة برمجة تطبيقات للتشغيل التفاعلي لإدراجها في RecyclerView أيضًا. وقد أتاح ذلك طرح إعدادات LazyColumn ضمن اختبار A/B جنبًا إلى جنب مع RecyclerView، أي إعادة استخدام عناصر Compose نفسها وتحسين الأداء، بدون تعطيل بقية أعضاء الفريق عن إنشاء الميزات وتحسينها.
شكّل حجم Instagram وتعقيده وحساسيته تجاه أصغر حالات التراجع تحديًا فريدًا لـ Jetpack Compose. ولمعالجة هذه المشاكل، كان من الضروري عقد شراكة عملية ومتكررة. من خلال العمل معًا عن كثب، حلّل مهندسو Google وMeta المقاييس لتحديد وتصميم إمكانات جديدة في Compose لتلبية مقاييس الأداء المستندة إلى View أو تجاوزها. نتيجةً لهذه الشراكة، تبرز الإضافات التالية إلى Jetpack Compose: التركيب القابل للإيقاف مؤقتًا باستخدام LazyLayoutCacheWindows وتتبُّع مستوى العرض.
إنشاء قابل للإيقاف مؤقتًا باستخدام LazyLayoutCacheWindows
تتيح ميزة "الإنشاء القابل للإيقاف مؤقتًا" (المفعَّلة تلقائيًا في Compose 1.10) إنشاء عناصر القائمة الكسولة التي تستهلك الكثير من الموارد بشكل تدريجي على مستوى اللقطات لمنع حدوث أي خلل. عند إقرانها مع LazyLayoutCacheWindow (المُضافة في Compose 1.9)، يؤدي هذا المزيج إلى تحسين سلاسة الانتقال بشكل كبير. في الاختبارات الداخلية التي أجرتها شركة Meta مؤخرًا، أدى الجمع بين ميزة Pausable composition ونافذة عرض واحدة LazyLayoutCacheWindow إلى تقليل حالات إسقاط اللقطات الكبيرة في الدقيقة (LFDs/m) بنسبة %13 تقريبًا مقارنةً بمكتبة Compose العادية. أما Cache Window، فقد خفّضت بمفردها استهلاك الطاقة بنسبة %8 تقريبًا مقارنةً بالمرجع نفسه. LFDs/m هو مقياس داخلي تستخدمه Meta لتتبُّع حالات التقطُّع الملحوظة أثناء الانتقال للأعلى أو للأسفل.
يؤدي استخدام LazyLayoutCacheWindow في تطبيقك إلى إعداد العناصر خارج الشاشة والاحتفاظ بها ضمن نطاق مستند إلى وحدات البكسل حول إطار العرض لإتاحة عمليات التمرير السريع. للاستفادة من LazyLayoutCacheWindows في تطبيقك، يمكنك استخدام أحدث إصدار من Compose 1.13.0-alpha03 وإعداده كما هو موضّح في المثال أدناه:
val cacheWindow = LazyLayoutCacheWindow(ahead = 150.dp, behind = 100.dp) // OR val cacheWindow = LazyLayoutCacheWindow(aheadFraction = 0.5f, behindFraction = 0.3f) LazyColumn(state = state, cacheWindow = cacheWindow) { ... }
هناك طريقتان لضبط نافذة ذاكرة التخزين المؤقت. يصف كلاهما الشيء نفسه: مقدار المحتوى خارج الشاشة الذي يجب الاحتفاظ به، ولكن بوحدات مختلفة.
- Dp: طول مطلق ثابت يحتفظ
ahead = 150.dpبمحتوى يبلغ حجمه 150 بكسل مستقل الكثافة (dp) بعد الحافة المرئية بغض النظر عن الجهاز. - Float: جزء من إطار العرض يحتفظ
aheadFraction = 0.5fبنصف الشاشة التي تم إنشاؤها مسبقًا، وبالتالي يتغيّر المقدار المطلق حسب ارتفاع الشاشة ليتوافق مع أشكال الأجهزة المختلفة: مقدار أكبر على جهاز لوحي أو جهاز قابل للطي غير مطوي، ومقدار أقل على هاتف صغير الحجم.
ضبط فريق Instagram أجزاء الأعداد العشرية في نافذة ذاكرة التخزين المؤقت خصيصًا لبنية محتوى Direct وأحجام العناصر. بما أنّ القيم المثالية تختلف حسب مَعلمات واجهة المستخدم المحدّدة، يتطلّب العثور على التوازن المناسب بعض التجربة.
تسجيل مرّات الظهور باستخدام onVisibilityChanged
كانت واجهة برمجة التطبيقات onVisibilityChanged (المُضافة في الإصدار 1.9.0 من Compose) نتيجة رئيسية أخرى للشراكة الفنية بين Google وMeta. وتوفّر هذه الواجهة طريقة متّسقة لمساحات العرض الكبيرة في Jetpack Compose لمعرفة متى تكون الدالة المركّبة مرئية على الشاشة، ما يحلّ محلّ عمليات التنفيذ المخصّصة واليدوية التي كانت تُستخدَم في السابق. في Instagram Direct وحده، يتم استخدام إشارات الظهور هذه في مئات الملفات لدعم مقاييس جودة المنتج التي تعتمد على ما إذا كانت عناصر في واجهة المستخدم قد تم عرضها بالفعل للأشخاص.
أداء بدء التشغيل
أدى استخدام Jetpack Compose في Instagram Direct إلى تحسينات غير متوقعة في الأداء على مستوى مساحات العرض الأخرى في التطبيق. يتطلب وقت تشغيل Jetpack Compose تكلفة إعداد يتم دفعها مرة واحدة فقط، وبما أنّ المراسلة هي مساحة عرض تشهد عددًا كبيرًا من الزيارات وغالبًا ما تتم زيارتها في وقت مبكر من جلسة المستخدم، شهدت مساحات العرض الأخرى على Instagram التي تعتمد على Compose تحسينات ملحوظة في الأداء.
تم تحسين أداء بدء تشغيل واجهة مستخدم Compose داخل Instagram Direct من خلال استخدام ملفات Baseline التي تُجمِّع مسبقًا المسارات البرمجية النشطة في وقت التثبيت، ما يتيح عرض Compose بسرعة من أول تشغيل.
الدروس المستفادة من نقل بيانات Instagram Direct إلى Jetpack Compose
- تحقّق أداة Jetpack Compose عائدًا فوريًا على الاستثمار: لست بحاجة إلى استخدام مهام سير عمل متقدّمة مستندة إلى الذكاء الاصطناعي للاستفادة من Compose. ومع تقليل الرموز البرمجية بنسبة %50 تقريبًا، يعني ذلك تقليل الرموز البرمجية التي يجب صيانتها وتقليل مساحة سطح الأخطاء.
- أدّى تصميم بنية مستندة إلى الذكاء الاصطناعي إلى تحقيق نجاحات كبيرة، بما في ذلك تقليل وقت تنفيذ وكيل الذكاء الاصطناعي بنسبة %35، وتقليل عمليات التبادل بين المهندسين والوكلاء بنسبة %32، وخفض تكلفة الرموز المميّزة بنسبة %33.
- على الرغم من توفّر العديد من واجهات برمجة التطبيقات الخاصة بإمكانية التشغيل التفاعلي وإتاحة الجمع بين Views وCompose معًا، يجب نقل مساحات العرض الأكبر حجمًا بدلاً من المكوّنات الصغيرة الفردية. يؤدي ذلك إلى إبقاء واجهة المستخدم ضمن تسلسل هرمي واحد غير منقطع للإنشاء، ويتيح جميع أفضل تحسينات الأداء المخصّصة لـ Compose.
- إقران دالة Pausable مع LazyLayoutCacheWindow: يؤدي إقران هاتين الدالتين معًا إلى تحقيق نتائج أفضل من استخدام نوافذ ذاكرة التخزين المؤقت وحدها. باستخدام نافذة ذاكرة التخزين المؤقت فقط، قد يحاول عنصر ثقيل الإنشاء في تمريرة واحدة، ما قد يؤدي إلى تجاوز ميزانية اللقطة.
- المساهمة في Compose نفسه تعاونت Meta مع فريق Jetpack Compose لتنفيذ ملاحظاتهم وأفكارهم في Compose. إنّ العمل على مجموعة أدوات مفتوحة المصدر يعني أنّنا نستفيد جميعًا عندما يتم إصلاح الأخطاء وتحسين الأداء بشكل مركزي. لذا، يُرجى مشاركة ملاحظاتك.
أدى استخدام Jetpack Compose إلى تحقيق مكاسب كبيرة في التطوير المستند إلى الذكاء الاصطناعي، مع تبسيط هندسة واجهة المستخدم اليومية في Instagram. يقلّل النهج التعريفي من الرموز المتكررة، ويسهّل فهم الحالة، ويحسّن إنتاجية المطوّرين بشكل عام. يتطلّع فريق هندسة Instagram إلى توفير Compose على المزيد من مساحات العرض في التطبيق، ومواصلة التعاون بين Google وMeta لتقديم المزيد من التحسينات لمستخدمي Instagram وJetpack Compose على حدٍ سواء.
إذا لم يسبق لك تجربة Compose، يمكنك الآن الاستعانة بالذكاء الاصطناعي لتسهيل عملية نقل البيانات إلى Jetpack Compose أكثر من أي وقت مضى.
الإقرارات: نشكر "ميشال زيلينسكي" و"ماثيو دو" من Meta، و"أندريه شيكوف" و"جورج ماونت" من Google، على جهودهم في تحسين أداء Compose من خلال التعاون بين Meta وGoogle. نشكر أيضًا "غاري يي" من Meta على المساعدة في توفير Compose في Instagram Direct، و"غوبال جونيجا" من Meta على دعم هذا الجهد من خلال علم البيانات.
-
دراسات الحالةتتطلّب تطبيقات إثبات الهوية للخدمات المصرفية وتسجيل شريحة SIM التقاط صور واضحة وعالية الدقة للوجه من أجل رصد عمليات الانتحال والتزييف العميق. يواجه مطوّرو تطبيقات الكاميرا على Android تحديًا شائعًا يتمثل في التقاط لقطات واضحة بما يكفي لإجراء عمليات التحقّق من الحيوية ومكافحة الانتحال، بدون أن يؤدي ذلك إلى تعطُّل الأجهزة ذات الذاكرة المنخفضة
Donovan McMurray • مدّة القراءة: 4 دقائق -
دراسات الحالةGrab هو التطبيق الفائق الرائد في جنوب شرق آسيا، ويقدّم خدمات التوصيل والتنقّل والخدمات المالية لملايين المستخدمين في ثمانية بلدان من خلال تطبيق واحد.
Ajesh Pai, Nguyen Van Minh, Tracy Agyemang • مدّة القراءة: 5 دقائق -
دراسات الحالةWhatsApp هي أكبر منصة مراسلة في العالم، ويستخدمها مليارات الأشخاص حول العالم. وهو أداة التواصل التلقائية للمستخدمين في مختلف المناطق، إذ يربط بينهم من خلال رسائل خاصة وموثوقة وآمنة.
Niharika Arora, Tracy Agyemang, Mayank Jain • مدّة القراءة: 8 دقائق
يمكنك الحصول على آخر الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.