در طول راه اندازی برنامه، برنامه شما اولین تاثیر را بر روی کاربران می گذارد. راهاندازی برنامه باید سریع باشد و اطلاعات مورد نیاز کاربر برای استفاده از برنامه شما را بارگیری و نمایش دهد. اگر راه اندازی برنامه شما بیش از حد طول بکشد، ممکن است کاربران از برنامه شما خارج شوند زیرا مدت زیادی منتظر هستند.
توصیه می کنیم از کتابخانه Macrobenchmark برای اندازه گیری راه اندازی استفاده کنید. این کتابخانه یک نمای کلی و ردیابی دقیق سیستم را برای مشاهده دقیق آنچه در هنگام راه اندازی اتفاق می افتد ارائه می دهد.
ردیابیهای سیستم اطلاعات مفیدی در مورد آنچه در دستگاه شما اتفاق میافتد ارائه میکند، که به شما کمک میکند بفهمید برنامه شما در حین راهاندازی چه میکند و مناطق بالقوه برای بهینهسازی را شناسایی کنید.
برای تجزیه و تحلیل راه اندازی برنامه خود، موارد زیر را انجام دهید:
- محیطی را برای ثبت ردیابی برای راه اندازی برنامه تنظیم کنید .
- ردیابی سیستم را درک کنید.
- با استفاده از Android Studio Profilers یا Perfetto در گزارش ردیابی پیمایش کنید.
مراحل تجزیه و تحلیل و بهینه سازی راه اندازی
برنامه ها اغلب نیاز به بارگیری منابع خاصی در هنگام راه اندازی دارند که برای کاربران نهایی حیاتی است. منابع غیر ضروری می توانند تا پایان راه اندازی صبر کنند تا بارگذاری شوند.
برای ایجاد معاوضه عملکرد، موارد زیر را در نظر بگیرید:
از کتابخانه Macrobenchmark برای اندازهگیری زمان صرف شده توسط هر عملیات، و شناسایی بلوکهایی که تکمیل آنها زمان زیادی میبرد، استفاده کنید.
تأیید کنید که عملیات فشرده منابع برای راه اندازی برنامه حیاتی است. اگر عملیات میتواند صبر کند تا برنامه به طور کامل کشیده شود، میتواند به به حداقل رساندن محدودیتهای منابع در هنگام راهاندازی کمک کند.
اطمینان حاصل کنید که انتظار دارید این عملیات هنگام راه اندازی برنامه اجرا شود. اغلب، عملیات غیر ضروری را می توان از کدهای قدیمی یا کتابخانه های شخص ثالث فراخوانی کرد.
در صورت امکان عملیات طولانی مدت را به پس زمینه منتقل کنید. فرآیندهای پسزمینه همچنان میتوانند بر استفاده از CPU در هنگام راهاندازی تأثیر بگذارند.
پس از بررسی کامل عملیات، میتوانید در مورد مبادله بین زمان بارگذاری و لزوم گنجاندن آن در راهاندازی برنامه تصمیم بگیرید. به یاد داشته باشید که هنگام تغییر گردش کار برنامه خود، پتانسیل رگرسیون یا شکستن تغییرات را نیز لحاظ کنید.
بهینه سازی کنید و دوباره اندازه گیری کنید تا زمانی که از زمان راه اندازی برنامه خود راضی شوید. برای اطلاعات بیشتر، به استفاده از معیارها برای شناسایی و تشخیص مشکلات مراجعه کنید.
اندازه گیری و تجزیه و تحلیل زمان صرف شده در عملیات اصلی
هنگامی که یک ردیابی کامل از راه اندازی برنامه دارید، به ردیابی نگاه کنید و زمان صرف شده برای عملیات اصلی مانند bindApplication
یا activityStart
را اندازه بگیرید. توصیه می کنیم از Perfetto یا Android Studio Profilers برای تجزیه و تحلیل این ردیابی ها استفاده کنید.
به زمان کلی صرف شده در طول راهاندازی برنامه نگاه کنید تا عملیاتهایی که موارد زیر را انجام میدهند شناسایی کنید:
- فریم های زمانی زیادی را اشغال می کند و می تواند بهینه شود. هر میلی ثانیه در عملکرد مهم است. به عنوان مثال، زمانهای ترسیم
Choreographer
، زمانهای تورم چیدمان، زمانهای بارگذاری کتابخانه، تراکنشهایBinder
یا زمانهای بارگذاری منبع را جستجو کنید. برای شروع کلی، به تمام عملیات هایی که بیش از 20 میلی ثانیه طول می کشد نگاه کنید. - تاپیک اصلی را مسدود کنید. برای اطلاعات بیشتر، به پیمایش یک گزارش Systrace مراجعه کنید.
- در هنگام راه اندازی نیازی به اجرا ندارید.
- می توانید تا زمانی که اولین فریم شما کشیده شود صبر کنید.
هر یک از این ردپاها را بیشتر بررسی کنید تا شکاف های عملکردی را بیابید.
عملیات گران قیمت را در موضوع اصلی شناسایی کنید
بهترین کار این است که عملیات گران قیمت مانند ورودی/خروجی فایل و دسترسی به شبکه را از موضوع اصلی دور نگه دارید. این در هنگام راهاندازی برنامه به همان اندازه مهم است، زیرا عملیات گرانقیمت روی رشته اصلی میتواند برنامه را پاسخگو نباشد و سایر عملیات حیاتی را به تاخیر بیندازد. StrictMode.ThreadPolicy
می تواند به شناسایی مواردی کمک کند که عملیات گران قیمت در رشته اصلی اتفاق می افتد. همانطور که در مثال زیر نشان داده شده است، تمرین خوبی است که StrictMode
در ساختهای اشکالزدایی فعال کنید تا مشکلات را در اسرع وقت شناسایی کنید:
کاتلین
class MyApplication : Application() { override fun onCreate() { super.onCreate() ... if (BuildConfig.DEBUG) StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyDeath() .build() ) ... } }
جاوا
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); ... if(BuildConfig.DEBUG) { StrictMode.setThreadPolicy( new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyDeath() .build() ); } ... } }
استفاده از StrictMode.ThreadPolicy
خطمشی رشته را در تمام ساختهای اشکالزدایی فعال میکند و هر زمان که نقض خطمشی رشته تشخیص داده شود، برنامه از کار میافتد، که این امر باعث میشود از دست دادن نقض خطمشی رشته مشکل شود.
TTID و TTFD
برای مشاهده زمان لازم برای تولید اولین فریم برنامه، زمان نمایش اولیه (TTID) را اندازه گیری کنید. با این حال، این معیار لزوماً زمان تا زمانی که کاربر بتواند با برنامه شما شروع به تعامل کند، منعکس نمی کند. متریک زمان برای نمایش کامل (TTFD) در اندازه گیری و بهینه سازی مسیرهای کد لازم برای داشتن یک وضعیت برنامه کاملاً قابل استفاده مفیدتر است.
برای استراتژیهای مربوط به گزارشدهی زمانی که رابط کاربری برنامه کاملاً ترسیم شده است، به بهبود دقت زمانبندی راهاندازی مراجعه کنید.
هم برای TTID و هم برای TTFD بهینه سازی کنید، زیرا هر دو در حوزه های خودشان مهم هستند. یک TTID کوتاه به کاربر کمک می کند تا ببیند که برنامه واقعاً در حال راه اندازی است. کوتاه نگه داشتن TTFD برای اطمینان از اینکه کاربر می تواند به سرعت با برنامه تعامل برقرار کند، مهم است.
وضعیت کلی نخ را تجزیه و تحلیل کنید
زمان راهاندازی برنامه را انتخاب کنید و به برشهای نخ کلی نگاه کنید. موضوع اصلی باید همیشه پاسخگو باشد.
ابزارهایی مانند Android Studio Profiler و Perfetto یک نمای کلی از موضوع اصلی و مدت زمان صرف شده در هر مرحله ارائه می دهند. برای اطلاعات بیشتر در مورد تجسم ردیابی پرفتو، به مستندات Perfetto UI مراجعه کنید.
تکه های اصلی حالت خواب نخ اصلی را شناسایی کنید
اگر زمان زیادی برای خواب سپری می شود، احتمالاً نتیجه این است که رشته اصلی برنامه شما منتظر تکمیل کار است. اگر یک برنامه چند رشته ای دارید، رشته ای را که موضوع اصلی شما منتظر آن است شناسایی کنید و بهینه سازی این عملیات را در نظر بگیرید. همچنین میتواند مفید باشد تا اطمینان حاصل شود که درگیری غیرضروری قفل وجود ندارد که باعث تاخیر در مسیر بحرانی شما شود.
انسداد نخ اصلی و خواب بی وقفه را کاهش دهید
به دنبال هر نمونه ای از موضوع اصلی باشید که در حالت مسدود شده است. Perfetto و Studio Profiler این را با یک نشانگر نارنجی در جدول زمانی وضعیت رشته نشان می دهند. عملیات را شناسایی کنید، بررسی کنید که آیا آنها مورد انتظار هستند یا می توان از آنها اجتناب کرد، و در صورت لزوم بهینه سازی کنید.
خواب قطعی مرتبط با IO می تواند فرصت خوبی برای بهبود باشد. سایر فرآیندهایی که IO را انجام می دهند، حتی اگر برنامه های نامرتبط باشند، می توانند با IO که برنامه برتر انجام می دهد مخالفت کنند.
بهبود زمان راه اندازی
پس از شناسایی فرصتی برای بهینه سازی، راه حل های ممکن را برای کمک به بهبود زمان راه اندازی بررسی کنید:
- برای سرعت بخشیدن به TTID ، محتوا را به صورت تنبل و ناهمزمان بارگیری کنید.
- توابع فراخوانی را که تماس های بایندر را ایجاد می کنند به حداقل برسانید. اگر غیرقابل اجتناب هستند، مطمئن شوید که آن تماسها را با ذخیره مقادیر بهجای تکرار تماسها یا انتقال کارهای غیرمسدود به رشتههای پسزمینه، بهینهسازی میکنید.
- برای اینکه راهاندازی برنامهتان سریعتر ظاهر شود، میتوانید چیزی را که نیاز به حداقل رندر برای کاربر دارد، در سریعترین زمان ممکن نمایش دهید تا زمانی که بقیه صفحه بارگیری شود.
- یک نمایه راه اندازی به برنامه خود ایجاد و اضافه کنید.
- از کتابخانه Jetpack App Startup برای ساده کردن مقداردهی اولیه مؤلفه ها در هنگام راه اندازی برنامه استفاده کنید.
تجزیه و تحلیل عملکرد UI
راه اندازی برنامه شامل یک صفحه نمایش و زمان بارگذاری صفحه اصلی شما است. برای بهینهسازی راهاندازی برنامه، ردیابیها را بررسی کنید تا زمان ترسیم رابط کاربری خود را درک کنید.
کار بر روی مقداردهی اولیه را محدود کنید
برخی از فریمها ممکن است زمان بیشتری برای بارگذاری نسبت به سایر فریمها نیاز داشته باشند. اینها قرعه کشی های گران قیمت برای برنامه در نظر گرفته می شوند.
برای بهینه سازی مقداردهی اولیه، موارد زیر را انجام دهید:
- پاسهای طرحبندی آهسته را اولویتبندی کنید و آنها را برای بهبود انتخاب کنید.
- هر اخطار Perfetto و هشدار از Systrace را با اضافه کردن رویدادهای ردیابی سفارشی برای کاهش قرعه کشی ها و تاخیرهای گران قیمت بررسی کنید.
داده های فریم را اندازه گیری کنید
روش های مختلفی برای اندازه گیری داده های فریم وجود دارد. پنج روش اصلی جمع آوری عبارتند از:
- مجموعه محلی با استفاده از
dumpsys gfxinfo
: همه فریمهای مشاهدهشده در دادههای dumpsys مسئول رندر آهسته برنامه شما نیستند یا تأثیری بر کاربران نهایی ندارند. با این حال، این معیار خوبی برای بررسی چرخه های مختلف انتشار برای درک روند کلی عملکرد است. برای کسب اطلاعات بیشتر در مورد استفاده ازgfxinfo
وframestats
برای ادغام اندازهگیریهای عملکرد رابط کاربری در روشهای آزمایشی خود، به اصول آزمایش برنامههای Android مراجعه کنید. - مجموعه فیلد با استفاده از JankStats : زمان های رندر فریم را از قسمت های خاصی از برنامه خود با کتابخانه JankStats جمع آوری کنید و داده ها را ضبط و تجزیه و تحلیل کنید.
- در آزمایشات با استفاده از Macrobenchmark (Perfetto در زیر کاپوت)
- Perfetto FrameTimeline : در Android 12 (سطح API 31)، میتوانید معیارهای جدول زمانی فریم را از یک Trace Perfetto که کار باعث افت فریم میشود، جمعآوری کنید. این می تواند اولین قدم برای تشخیص علت افت فریم ها باشد.
- نمایه اندروید استودیو برای تشخیص jank
زمان بارگذاری فعالیت اصلی را بررسی کنید
فعالیت اصلی برنامه شما ممکن است حاوی مقدار زیادی اطلاعات باشد که از چندین منبع بارگیری شده است. طرحبندی Home Activity
را بررسی کنید و به طور خاص به روش Choreographer.onDraw
فعالیت خانه نگاه کنید.
- از
reportFullyDrawn
استفاده کنید تا به سیستم گزارش دهید که اکنون برنامه شما به طور کامل برای اهداف بهینه سازی طراحی شده است. - فعالیت و راه اندازی برنامه را با استفاده از
StartupTimingMetric
با کتابخانه Macrobenchmark اندازه گیری کنید. - به افت فریم نگاه کنید.
- طرحبندیهایی را که رندر یا اندازهگیری زمان زیادی طول میکشد، شناسایی کنید.
- دارایی هایی را شناسایی کنید که زمان زیادی برای بارگذاری آنها نیاز است.
- طرحبندیهای غیرضروری را که در هنگام راهاندازی متورم میشوند، شناسایی کنید.
این راه حل های ممکن را برای بهینه سازی زمان بارگذاری فعالیت اصلی در نظر بگیرید:
- طرح اولیه خود را تا حد امکان ساده کنید. برای اطلاعات بیشتر، به بهینه سازی سلسله مراتب طرح بندی مراجعه کنید.
- نقاط ردیابی سفارشی را اضافه کنید تا اطلاعات بیشتری در مورد فریم های افت شده و طرح بندی های پیچیده ارائه دهید.
- تعداد و اندازه منابع بیت مپ بارگیری شده در هنگام راه اندازی را به حداقل برسانید.
در جایی که طرحبندیها بلافاصله
VISIBLE
نیستند، ازViewStub
استفاده کنید.ViewStub
یک نمای نامرئی و با اندازه صفر است که می تواند برای افزایش تنبلی منابع طرح بندی در زمان اجرا مورد استفاده قرار گیرد. برای اطلاعات بیشتر،ViewStub
را ببینید.اگر از Jetpack Compose استفاده میکنید، میتوانید رفتاری مشابه
ViewStub
با استفاده از حالت برای به تعویق انداختن بارگیری برخی از مؤلفهها داشته باشید:var shouldLoad by remember {mutableStateOf(false)} if (shouldLoad) { MyComposable() }
با تغییر
shouldLoad
، composeable ها را در داخل بلوک شرطی بارگذاری کنید:LaunchedEffect(Unit) { shouldLoad = true }
این یک ترکیب مجدد را آغاز می کند که شامل کد داخل بلوک شرطی در قطعه اول است.
برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- معیارهای ماکرو بنچمارک را ضبط کنید
- بررسی اجمالی اندازه گیری عملکرد برنامه * فریم های منجمد