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

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

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

عملکرد طرح‌بندی و اندازه‌گیری

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

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

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

چون نمی‌توانید این عملیات را به رشته عامل منتقل کنید (برنامه شما باید آن‌ها را در رشته اصلی پردازش کند)، بهتر است آن‌ها را بهینه‌سازی کنید تا کمترین زمان ممکن را بگیرند.

مدیریت چیدمان‌های پیچیده

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

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

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

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

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

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

مالیات مضاعف

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

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

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

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

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

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

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

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

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

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

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

Perfetto

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

پردازش GPU نمایه

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

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

Lint

ابزار Lint در Android Studio می‌تواند به شما کمک کند تا ناکارآمدی‌ها را در سلسله‌مراتب نما تشخیص دهید. برای استفاده از این ابزار، Analyze > Inspect Code را انتخاب کنید، همان‌طور که در شکل ۱ نشان داده شده است.

شکل ۱. بازرسی کد را در «استودیو Android» انتخاب کنید.

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

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

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

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

بازرس چیدمان

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

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

برای اطلاعات بیشتر، اشکال‌زدایی چیدمان با «بازرس چیدمان» و «اعتبارسنجی چیدمان» را ببینید.

حل کردن مشکلات سلسله‌مراتب نما

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

برداشتن طرح‌بندی‌های تودرتوی زائد

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

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

دستور include قبلی به‌طور غیرضروری چیدمان اول را در چیدمان دوم تودرتو می‌کند.

برچسب <merge> می‌تواند به جلوگیری از این مشکل کمک کند. برای اطلاعات درباره این برچسب، به استفاده از برچسب <merge> مراجعه کنید.

انتخاب کردن چیدمان ارزان‌تر

ممکن است نتوانید طرح‌بندی موجودتان را طوری تنظیم کنید که طرح‌بندی‌های زائد نداشته باشد. در برخی موارد، تنها راه‌حل ممکن است مسطح کردن سلسله‌مراتب با جابه‌جایی به نوع چیدمان کاملاً متفاوتی باشد.

برای مثال، ممکن است متوجه شوید که TableLayout همان عملکرد را به‌عنوان یک چیدمان پیچیده‌تر با وابستگی‌های موقعیتی متعدد ارائه می‌دهد. کتابخانه Jetpack ConstraintLayout عملکردی مشابه RelativeLayout ارائه می‌دهد، به‌علاوه ویژگی‌های بیشتری برای کمک به ایجاد چیدمان‌های مسطح‌تر و کارآمدتر.