سلسله مراتب عملکرد و مشاهده

روشی که شما سلسله مراتب اشیاء View خود را مدیریت می کنید می تواند به طور قابل توجهی بر عملکرد برنامه شما تأثیر بگذارد. این صفحه نحوه ارزیابی اینکه آیا سلسله مراتب دید شما سرعت برنامه شما را کاهش می دهد یا خیر، توضیح می دهد و چند استراتژی برای رسیدگی به مشکلاتی که ممکن است ایجاد شود ارائه می دهد.

این صفحه بر روی بهبود طرح‌بندی‌های مبتنی بر View تمرکز دارد. برای اطلاعات در مورد بهبود عملکرد Jetpack Compose، به عملکرد Jetpack Compose مراجعه کنید.

چیدمان و اندازه گیری عملکرد

خط لوله رندر شامل یک مرحله طرح بندی و اندازه گیری است که در طی آن سیستم موارد مربوطه را به طور مناسب در سلسله مراتب دید شما قرار می دهد. قسمت اندازه گیری این مرحله اندازه و مرزهای اشیاء View را تعیین می کند. قسمت layout تعیین می کند که در کجای صفحه View اشیاء قرار گیرد.

هر دوی این مراحل خط لوله هزینه کمی را برای هر نما یا طرحی که پردازش می کنند متحمل می شوند. بیشتر اوقات، این هزینه حداقل است و تأثیر قابل توجهی بر عملکرد ندارد. با این حال، زمانی که یک برنامه اشیاء View را اضافه یا حذف می‌کند، بیشتر می‌شود، مانند زمانی که یک شی RecyclerView آنها را بازیافت یا استفاده مجدد می‌کند. اگر یک شی View نیاز به تغییر اندازه داشته باشد تا محدودیت های خود را برآورده کند، هزینه نیز می تواند بیشتر باشد. به عنوان مثال، اگر برنامه شما SetText() را روی یک شی View که متن را بسته بندی می کند فراخوانی کند، ممکن است View نیاز به تغییر اندازه داشته باشد.

اگر مواردی از این دست بیش از حد طول بکشد، می‌توانند از رندر شدن یک فریم در 16 میلی‌ثانیه مجاز جلوگیری کنند، که می‌تواند فریم‌ها را پایین بیاورد و انیمیشن را ناخوشایند کند.

از آنجایی که نمی‌توانید این عملیات‌ها را به یک رشته worker منتقل کنید - برنامه شما باید آنها را در رشته اصلی پردازش کند - بهتر است آنها را بهینه کنید تا کمترین زمان ممکن را صرف کنند.

طرح بندی های پیچیده را مدیریت کنید

طرح‌بندی‌های Android به شما امکان می‌دهند اشیاء رابط کاربری را در سلسله‌مراتب view قرار دهید. این تودرتو همچنین می تواند هزینه چیدمان را تحمیل کند. هنگامی که برنامه شما یک شی را برای طرح‌بندی پردازش می‌کند، برنامه نیز همین فرآیند را روی همه فرزندان طرح‌بندی انجام می‌دهد.

برای یک طرح‌بندی پیچیده، گاهی هزینه‌ها تنها در اولین باری که سیستم طرح‌بندی را محاسبه می‌کند، ایجاد می‌شود. به عنوان مثال، وقتی برنامه شما یک آیتم لیست پیچیده را در یک شی RecyclerView بازیافت می کند، سیستم باید همه اشیا را چیدمان کند. در مثالی دیگر، تغییرات بی اهمیت می توانند زنجیره را به سمت والد پخش کنند تا زمانی که به شیئی برسند که بر اندازه والد تأثیری نداشته باشد.

یک دلیل متداول برای طولانی‌مدت چیدمان زمانی است که سلسله مراتب اشیاء View درون یکدیگر قرار گرفته‌اند. هر شی layout تو در تو هزینه را به مرحله طرح اضافه می کند. هر چه سلسله مراتب شما صاف تر باشد، زمان کمتری طول می کشد تا مرحله چیدمان کامل شود.

توصیه می‌کنیم به جای RelativeLayout یا LinearLayout از Layout Editor برای ایجاد ConstraintLayout استفاده کنید، زیرا معمولاً هم کارآمدتر است و هم تودرتوی طرح‌بندی‌ها را کاهش می‌دهد. با این حال، برای طرح‌بندی‌های ساده‌ای که می‌توان با استفاده از FrameLayout به دست آورد، توصیه می‌کنیم از FrameLayout استفاده کنید.

اگر از کلاس RelativeLayout استفاده می کنید، ممکن است بتوانید با استفاده از نماهای LinearLayout تودرتو و بدون وزن، به همان اثر با هزینه کمتر دست پیدا کنید. با این حال، اگر از نماهای تودرتو و وزن دار LinearLayout استفاده می کنید، هزینه چیدمان بسیار بالاتر است زیرا به چندین پاس طرح نیاز دارد، همانطور که در بخش بعدی توضیح داده شد.

ما همچنین استفاده از RecyclerView به جای ListView توصیه می‌کنیم، زیرا می‌تواند طرح‌بندی آیتم‌های فهرست را بازیافت کند، که هم کارآمدتر است و هم عملکرد اسکرول را بهبود می‌بخشد.

مالیات مضاعف

به طور معمول، چارچوب مرحله طرح یا اندازه گیری را در یک پاس اجرا می کند. با این حال، با برخی از موارد طرح‌بندی پیچیده، چارچوب ممکن است مجبور باشد چندین بار در قسمت‌هایی از سلسله مراتب که برای حل آن‌ها نیاز به عبور چندگانه دارند، قبل از در نهایت موقعیت‌یابی عناصر تکرار شود. به انجام بیش از یک تکرار طرح و اندازه‌گیری، مالیات مضاعف گفته می‌شود.

به عنوان مثال، هنگامی که از ظرف RelativeLayout استفاده می کنید، که به شما امکان می دهد اشیاء View را با توجه به موقعیت های سایر اشیاء View قرار دهید، فریم ورک دنباله زیر را انجام می دهد:

  1. یک پاس طرح‌بندی و اندازه‌گیری را اجرا می‌کند، که در طی آن چارچوب موقعیت و اندازه هر شی فرزند را بر اساس درخواست هر کودک محاسبه می‌کند.
  2. از این داده ها با در نظر گرفتن وزن اشیا برای تعیین موقعیت مناسب نماهای همبسته استفاده می کند.
  3. یک پاس طرح دوم را برای نهایی کردن موقعیت اشیا انجام می دهد.
  4. به مرحله بعدی فرآیند رندر منتقل می شود.

هرچه سلسله مراتب دید شما دارای سطوح بیشتری باشد، احتمال جریمه عملکرد بیشتر است.

همانطور که قبلا ذکر شد، ConstraintLayout به طور کلی کارآمدتر از طرح‌بندی‌های دیگر به جز FrameLayout است. کمتر مستعد دریافت چند طرح بندی است و در بسیاری از موارد نیاز به چیدمان های تودرتو را برطرف می کند.

کانتینرهای غیر از RelativeLayout نیز ممکن است مالیات مضاعف را افزایش دهند. به عنوان مثال:

  • اگر نمای LinearLayout به صورت افقی قرار دهید، می تواند منجر به یک پاس طرح بندی و اندازه گیری دوگانه شود. یک پاس طرح‌بندی و اندازه‌گیری دوتایی نیز ممکن است در جهت عمودی رخ دهد، اگر measureWithLargestChild اضافه کنید، در این صورت ممکن است فریم‌ورک باید یک پاس دوم را انجام دهد تا اندازه‌های مناسب اشیا را حل کند.
  • GridLayout همچنین موقعیت یابی نسبی را امکان پذیر می کند، اما معمولاً با پیش پردازش روابط موقعیتی بین نماهای فرزند، از مالیات مضاعف جلوگیری می کند. با این حال، اگر طرح‌بندی از وزن‌ها استفاده کند یا با کلاس Gravity پر شود، مزیت پیش‌پردازش از بین می‌رود و اگر کانتینر یک RelativeLayout باشد، ممکن است فریم ورک مجبور باشد چندین پاس را انجام دهد.

پاس‌های چندگانه طرح‌بندی و اندازه‌گیری لزوماً بار عملکردی نیستند. با این حال، اگر در مکان نامناسبی قرار بگیرند، می توانند به یک بار تبدیل شوند. مراقب شرایطی باشید که یکی از شرایط زیر در مورد ظرف شما صدق می کند:

  • این یک عنصر ریشه در سلسله مراتب دیدگاه شما است.
  • این یک سلسله مراتب دید عمیق در زیر خود دارد.
  • نمونه‌های زیادی وجود دارد که صفحه را پر می‌کند، مشابه کودکان در یک شی ListView .

مشکلات سلسله مراتب مشاهده را تشخیص دهید

عملکرد چیدمان یک مشکل پیچیده با جنبه های مختلف است. ابزارهای زیر می‌توانند به شما در شناسایی نقاط ضعف عملکرد کمک کنند. برخی از ابزارها اطلاعات قطعی کمتری ارائه می دهند اما می توانند نکات مفیدی را ارائه دهند.

پرفتو

Perfetto ابزاری است که داده های مربوط به عملکرد را ارائه می دهد. می‌توانید Traces Android را در Perfetto UI باز کنید.

نمایش GPU نمایه

ابزار نمایش GPU نمایه روی دستگاه، که در دستگاه‌های مجهز به Android 6.0 (سطح API 23) و بالاتر موجود است، می‌تواند اطلاعات دقیقی درباره تنگناهای عملکرد در اختیار شما قرار دهد. این ابزار به شما امکان می‌دهد ببینید که مرحله طرح‌بندی و اندازه‌گیری برای هر فریم رندر چقدر طول می‌کشد. این داده‌ها می‌توانند به شما در تشخیص مشکلات عملکرد زمان اجرا کمک کنند و به شما کمک کنند تا تعیین کنید که چه مسائلی را باید در مورد چیدمان و اندازه‌گیری بشناسید.

در نمایش گرافیکی داده‌هایی که می‌گیرد، رندر GPU Profile از رنگ آبی برای نمایش زمان چیدمان استفاده می‌کند. برای اطلاعات بیشتر در مورد نحوه استفاده از این ابزار، سرعت رندر GPU نمایه را ببینید.

لینت

ابزار لینت اندروید استودیو می‌تواند به شما کمک کند تا حس ناکارآمدی در سلسله‌مراتب مشاهده را به دست آورید. برای استفاده از این ابزار، همانطور که در شکل 1 نشان داده شده است، Analyze > Inspect Code را انتخاب کنید.

شکل 1. Inspect Code را در Android Studio انتخاب کنید.

اطلاعات مربوط به موارد مختلف طرح‌بندی در زیر Android > Lint > Performance ظاهر می‌شود. برای مشاهده جزئیات بیشتر، روی هر مورد کلیک کنید تا آن را بزرگ کنید و اطلاعات بیشتری را در قسمت سمت راست صفحه نمایش دهید. شکل 2 نمونه ای از اطلاعات گسترش یافته را نشان می دهد.

شکل 2. مشاهده اطلاعات در مورد مسائل خاصی که ابزار Lint شناسایی می کند.

با کلیک بر روی یک مورد، مشکلات مربوط به آن مورد در پنجره سمت راست نشان داده می شود.

برای درک بیشتر در مورد موضوعات و مسائل خاص در این زمینه، به مستندات Lint مراجعه کنید.

بازرس چیدمان

ابزار Layout Inspector اندروید استودیو یک نمایش بصری از سلسله مراتب نمایش برنامه شما ارائه می دهد. این یک راه خوب برای پیمایش سلسله مراتب برنامه شما است، یک نمایش بصری واضح از زنجیره اصلی یک نمای خاص ارائه می‌کند و به شما امکان می‌دهد طرح‌بندی‌هایی را که برنامه شما می‌سازد بررسی کنید.

نظراتی که Layout Inspector ارائه می دهد می تواند به شناسایی مشکلات عملکرد ناشی از مالیات مضاعف نیز کمک کند. همچنین می‌تواند راهی برای شناسایی زنجیره‌های عمیق طرح‌بندی‌های تودرتو، یا مناطق چیدمان با تعداد زیادی بچه تودرتو، که می‌تواند منبعی برای هزینه‌های عملکرد باشد، فراهم کند. در این موارد، مراحل چیدمان و اندازه گیری می تواند پرهزینه باشد و منجر به مشکلات عملکرد شود.

برای اطلاعات بیشتر، به اشکال‌زدایی طرح‌بندی خود با Layout Inspector و Layout Validation مراجعه کنید.

مسائل مربوط به سلسله مراتب مشاهده را حل کنید

مفهوم اساسی در پس حل مشکلات عملکردی که از سلسله مراتب دیدگاه ناشی می شوند، می تواند در عمل دشوار باشد. جلوگیری از اعمال جریمه‌های عملکرد سلسله مراتبی شامل صاف کردن سلسله مراتب دید و کاهش مالیات مضاعف است. در این بخش راهکارهایی برای دستیابی به این اهداف مورد بحث قرار می گیرد.

طرح بندی های تو در تو اضافی را حذف کنید

ConstraintLayout یک کتابخانه Jetpack با تعداد زیادی مکانیسم مختلف برای موقعیت یابی نماها در طرح است. این نیاز به تودرتو کردن یک ConstaintLayout را کاهش می‌دهد و می‌تواند به صاف کردن سلسله مراتب view کمک کند. معمولاً صاف کردن سلسله مراتب با استفاده از ConstraintLayout در مقایسه با سایر انواع طرح‌بندی ساده‌تر است.

توسعه دهندگان اغلب از چیدمان های تو در تو بیشتر از حد لازم استفاده می کنند. به عنوان مثال، یک ظرف RelativeLayout ممکن است حاوی یک فرزند واحد باشد که همچنین یک ظرف RelativeLayout است. این تودرتو اضافی است و هزینه های غیر ضروری را به سلسله مراتب view اضافه می کند. 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 ، به علاوه ویژگی های بیشتر برای کمک به ایجاد طرح بندی های صاف تر و کارآمدتر ارائه می دهد.