أداء IOS - الرسوم المتحركة الأساسية والعرض خارج الشاشة وتتبع النظام. الجزء 2



كيفية تجنب مشاكل الأداء مع الإعداد المسبق الأساسي للرسوم المتحركة ، وما يجب استخدامه لتتبع أجزاء التعليمات البرمجية ومع الوظائف التي تقلل من حصة العمليات الحسابية في التطبيق من 26٪ إلى 0.6٪ - اقرأ الجزء الثاني من المقالة بناءً على مواد تقرير Luke Parkham في مؤتمر MBLT DEV العام الماضي . الجزء الأول من المقالة متاح هنا .


تحت القط ، ليس فقط نصائح مفيدة ، ولكن أيضًا أحدث تذاكر الطيور المبكرة لـ MBLT DEV 2018 - يمكنك شرائها اليوم فقط.


الرسوم المتحركة الأساسية


Core Animation (CA) هو إعداد مسبق في ملف التعريف يستخدم قياسات FPS (إطارات في الثانية) لمعرفة ما إذا كانت الرسوم المتحركة متخلفة أم لا. في كثير من الأحيان ، حتى لو تم العثور على مناطق مشكلة التطبيق ، تبقى صعوبات الأداء. والسبب هو أنه عند العمل مع أطر عمل واجهة المستخدم ، يتم استخدام UIView ، ولكن يتم إنشاء مثيل من CATransaction تحت الغطاء (أو يقوم النظام بذلك بنفسه) ، ويتم إرسال جميع هذه التعليمات إلى الخادم للمعالجة. خادم العرض مسؤول عن إنشاء الرسوم المتحركة. إذا تم تنفيذ رسم متحرك باستخدام UIView ، على سبيل المثال ، أسلوب فئة animate(withDuration:animations:) ، تتم معالجته بواسطة خادم التقديم ، والذي يعتبر سلسلة منفصلة ويعمل مع جميع الرسوم المتحركة في التطبيق.


يمكنك جعل خادم التقديم يعمل ببطء حتى لا يظهر في Time Profiler ، ولكنه سيبطيء في التطبيق. إليك ما يبدو عليه:







في الجزء العلوي هو جهاز استشعار معدل الإطار. فيما يلي الجزء الأكثر أهمية - خيارات التصحيح. هناك نوعان من المفاتيح ومع ذلك من السهل تكوين المعلمات. الأول هو color blended layers . إصلاحه بسيط للغاية. في الواقع ، تنشأ المشاكل حتى في iMessage ، تطبيق Apple المحبوب بالكامل.




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


القاعدة رقم 3


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




عرض خارج الشاشة


الخيار التالي هو العرض خارج الشاشة. إذا قمت بتمكين هذه الوظيفة ، فسيتم تمييز الأقسام باللون الأصفر.

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




على سبيل المثال ، على iPhone 6s ، يتم تحميلها ببطء إلى حد ما. وإذا نظرت إليها على iPhone 5 أو على طراز iPod القديم ، فسيكون التنزيل أبطأ. هذا يرجع إلى حقيقة أن التقديم داخل النظام أسوأ بكثير من مزج ألفا. يتم تحميل GPU. ونتيجة لذلك ، يتعين على الجهاز إجراء حسابات إضافية باستمرار بين معالج الرسومات والمعالج المركزي ، لذلك هناك تأخيرات إضافية يمكن تجنبها في معظم الحالات.


القاعدة رقم 4


لا تستخدم معلمة cornerRadius . يؤدي استخدام viewLayer.cornerRadius إلى عرض خارج الشاشة. بدلاً من ذلك ، يمكنك استخدام فئة UIBezierPath ، بالإضافة إلى شيء مشابه للعمل مع CGBitMap ، كما كان الحال مع فك تشفير JPEG من قبل. في هذه الحالة ، UIGraphics context .




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




على صفحة GIF - Twitter. تظهر الصورة في الوقت الحقيقي. من المفترض أن تفتح الصفحة وتعطي معلومات ، لكن النص والعناصر الأخرى للشاشة مرت بعرض خارج الشاشة ، لذلك تتحرك الرسوم المتحركة ببطء شديد.


القاعدة رقم 5


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


تسريع


  • تجنب عرض ومزج الطبقات الشفافة.
  • استخدمها فقط عندما لا يمكنك الاستغناء عنها. يظهر العرض خارج الشاشة نظرًا لوجود الظلال والزوايا الدائرية وما إلى ذلك.
  • جعل الصور معتمة.
  • لا تستخدم الزاوية Radius ، استخدم منحنيات بيزييه.
  • عند العمل مع النص ، لا تستخدم خاصية layer.shadow ، استبدلها بـ NSShadow.


تتبع النشاط


تتبع النشاط مشابه لما يفعله Time Profiler ، ولكن على نطاق أصغر. يسمح لك بالنظر في التدفقات وتفاعلها مع بعضها البعض.

القاعدة رقم 6


استخدم تتبع النظام لتتبع الفترات الزمنية لأحداث معينة. يمكنك التوصل إلى طريقة لتتبع الأحداث أو أقسام التعليمات البرمجية ومعرفة مقدار الوقت الذي تستغرقه في العمل الحقيقي للتطبيق. يوفر System Trace معلومات حول ما يحدث في النظام:


  • تشير "Sing Post" إلى حدوث شيء مهم.
  • العلامات هي أحداث فردية تستحق المشاهدة ، على سبيل المثال ، ظهور الرسوم المتحركة.
  • من خلال الفاصل الزمني للحدث ، يمكنك تتبع المدة التي يستغرقها فك التشفير.




لذلك ، يوضح البرنامج كيف يتفاعل الرمز مع بقية النظام.


على الشاشة مثال على إنشاء قالب تتبع النظام:


  • 1 - تحميل صورة
  • 2 - فك تشفير الصور
  • 3 - إمالة الرسوم المتحركة.

تحتاج إلى إضافة بعض الخيارات لفهم اللون الذي سيظهر. عادة ، يتم تعيين أرقام ، مثل 1 أو 2 ، وتتحول إلى اللون الأحمر أو الأخضر ، اعتمادًا على الإعداد. في Objective-C ، تحتاج إلى كتابة الأمر #import لـ kdebug_signpost . في Swift ، فهي متاحة بالفعل.




ثم تحتاج إلى استدعاء هذه الوظيفة kdebug_signpost أو kdebug_signpost_start و kdebug_signpost_end .




نشير إلى 3 أحداث جنبًا إلى جنب مع الأرقام المكتوبة في الرمز ، وعنصر أساسي لكل حدث معين. يشير الرقم الأخير إلى اللون. على سبيل المثال ، 2 باللون الأحمر.


التالي هي أحداث مهمة ، أشياء خاصة. يتم وصف مخطط مبسط في مشروع اختبار Luke على Swift.


تُظهر لقطة الشاشة كيف ستبدو عند بدء التتبع. في البداية ، عندما يتم تشغيل التطبيق ، لن يعطي البرنامج معلومات ، ولكن بمجرد تعطل التطبيق ، سنرى الحسابات.




يستغرق تنزيل الصور حوالي 200 مللي ثانية. ثم يأتي فك التشفير ، الذي يستغرق حوالي 40 مللي ثانية. من المفيد تتبع هذه البيانات إذا كان هناك العديد من العمليات في التطبيق. يمكنك سرد الأحداث في البرنامج ، ثم ملاحظة وتلقي معلومات حول مقدار الوقت المطلوب لتنفيذها ، وكيفية تفاعلها مع بعضها البعض.


أدوات إضافية


على الشاشة - مشروع AR لتصوير بطيء الحركة للهاتف الذكي. التطبيق مشابه لـ Snapchat. استخدم تأثير إعادة لمس الصورة ، ولكل إطار تم إنفاق 26.4 ٪ من جميع عمليات الحوسبة عليه. وبسبب هذا ، كانت الكاميرا تطلق ببطء ، حوالي 10 إطارات في الثانية. عند الدراسة ، نرى أن الخط الأعلى قام بمعظم العمل. كانت مسؤولة عن إرسال البيانات بنشاط. إذا قمت بفحص أسباب انخفاض الأداء ، ستلاحظ أن النقطة هي الاستخدام المكثف لـ NSDispatchData .




تتلقى هذه الفئة الفرعية من NSData فقط سلسلة من وحدات البايت باستخدام طريقة getBytes في فاصل زمني معين وتمريرها إلى موقع آخر. يبدو أن الأمر بسيط للغاية ، ومع ذلك ، فإن كل شيء تقوم به هذه الطريقة داخليًا يأخذ 18 ٪ من 26 ٪ من الحسابات.




القاعدة رقم 1


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

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




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




القاعدة رقم 2


تجنب تداخل وحدات البكسل على بعضها البعض عند إنشاء تطبيق يحتوي على تجسيد.

في معظم الحالات ، سيحدث ذلك بتردد أعلى من 60 إطارًا في الثانية. باستخدام CADisplayLink ، يمكنك إبطاء تحديث واجهة المستخدم. يوجد معلمة preferredFramesPerSecond FramesPerSecond. ينطبق فقط على iOS 10 والإصدارات الأحدث. بالنسبة للأنظمة الأقدم ، عليك القيام بذلك يدويًا. عند العمل في إصدارات جديدة من iOS ، يمكنك تعيين العدد المطلوب من الإطارات في الثانية. في معظم الحالات ، 15 إطارًا في الثانية أو نحو ذلك ، حتى لا تضيع طاقة الحوسبة ولا تضيف عملًا غير ضروري للتطبيق.




القاعدة رقم 3


عند العمل مع Objective-C ، من المفيد استخدام التخزين المؤقت لمؤشرات IMP (مؤشرات لتطبيق الأساليب). عندما يتم استدعاء الأسلوب under the hood في Objective-C ، يتم objc_msgSend() الدالة objc_msgSend() . إذا أظهر التتبع أن المكالمة تستغرق وقتًا طويلاً ، فيمكنك التخلص منها. في الواقع ، هذا هو مستودع ذاكرة التخزين المؤقت مع مؤشرات إلى وظيفة ، ويمكن إعطاؤها أسماء بعض الطرق. لذلك ، بدلاً من إجراء هذا البحث في كل مرة ، يجدر القيام بالتخزين المؤقت على النحو التالي: ضع مؤشرات دالة في ذاكرة التخزين المؤقت واتصل بها مباشرة. عادة ما يحدث هذا مرتين بسرعة.




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


القاعدة رقم 4


لا تستخدم ARC (العد المرجعي التلقائي). يضيف ARC الكثير من العمل الإضافي.


عندما يتم تمكين ARC ، فإن المترجم نفسه ينثر / release في الأماكن الصحيحة. ومع ذلك ، إذا كانت هناك أماكن تستغرق retain release الكثير من الوقت ، ففكر في إسقاط ARC. افعل ذلك إذا كان التحسين ضروريًا ، حيث سيستغرق الكثير من الوقت.


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


مواد مفيدة


الجزء الأول من المقالة متاح هنا . للحصول على نظرة ثاقبة للموضوع ، يوصي Luke Parham بقراءة كتاب " iOS و MacOS: ضبط الأداء " ومشاهدة دروسه.


تسجيل الفيديو لتقرير Luke عن MBLT DEV 2017 الآن في المجال العام:



المزيد من المعرفة والنصائح في MBLT DEV 2018


أعلن المتحدثون الأول :


  • سيتحدث John C. Fox من Netflix عن الأقلمة عالية الجودة ، ويعمل مع ظروف الشبكة القاسية واختبار A / B.
  • تُعد Krzysztof Zabłocki ، اوقات نيويورك ، تقريرًا عن الأنماط في iOS.
  • تتحدث لورا مورينيجو ، خبيرة مطوري Google ، عن أفضل ممارسات Firebase.

سوف تطير أحدث تذاكر الطيور المبكرة اليوم.


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


All Articles