پاسخ سریع و خلاصه کلیدی (Executive Architecture Summary)
بیس لاین پروفایل (Baseline Profile) در اندروید مشخصه ای پیکربندی شده از متدها، کلاس ها و مسیرهای اجرای بحرانی کد است که همراه با پکیج APK یا Android App Bundle (AAB) منتشر می شود.
ماشین مجازی زمان اجرای اندروید (Android Runtime یا ART) با بهره گیری از این اطلاعات، کدهای حیاتی را پیش از اولین اجرای برنامه (Ahead-Of-Time یا AOT) در هنگام نصب یا به روزرسانی به کد ماشین نیتیو کامپایل می کند.
این مکانیزم نیاز به مفسر اولیه (Interpreter) و فرآیند کند کامپایل حین اجرا (JIT Compilation) را در لحظات حساس شروع برنامه به شدت کاهش داده و زمان Cold Startup را بین ۳۰ تا ۴۰ درصد کوتاه می کند و لکنت های فریم (Jank) در اسکرول اولیه کامپوز را به طور کامل از بین می برد.
۱. معماری زمان اجرای اندروید (ART): تکامل از Dalvik و JIT تا Profile-Guided AOT
برای درک چرایی اختراع بیس لاین پروفایل ها توسط مهندسان گوگل، باید تاریخچه تکامل ماشین های مجازی در سیستم عامل اندروید را مرور کنیم:
- دوران ماشین مجازی دالویک (Dalvik VM): در نسخه های اولیه اندروید (تا نسخه ۴.۴)، کدهای بایت کد DEX در زمان اجرا توسط یک مفسر خط به خط به دستورات پردازنده ترجمه می شدند. بعدها یک کامپایلر Just-In-Time (JIT) ساده اضافه شد که متدهای داغ را حین اجرا کامپایل می کرد؛ اما سرعت اجرای اپ ها همچنان بسیار کند بود.
- معرفی موتور ART و کامپایل کامل AOT (اندروید ۵ و ۶): گوگل دالویک را کنار گذاشت و Android Runtime (ART) را معرفی کرد. در این نسل، کل کدهای برنامه در لحظه نصب توسط ابزار
dex2oatبه باینری نیتیو (ELF/OAT) کامپایل می شد. اگرچه سرعت اجرای اپ فوق العاده بود، اما زمان نصب اپلیکیشن ها چندین دقیقه طول می کشید و حجم اشغال شده در حافظه ذخیره سازی دستگاه چند برابر می شد. - رویکرد هیبریدی و کامپایل هدایت شده با پروفایل (Profile-Guided Compilation از اندروید ۷ به بعد): گوگل متوجه شد تنها ۲۰ درصد از کدهای یک اپلیکیشن (صفحه ورود، صفحه خانه، کتابخانه های رندر) بیش از ۸۰ درصد زمان اجرا را به خود اختصاص می دهند. بنابراین سیستمی پیاده شد که برنامه ابتدا با مفسر و JIT اجرا شود؛ رفتارهای کاربر رصد گردد و در زمان بیکاری دستگاه در شارژ (Idle Maintenance)، کدهای پرتکرار به کد ماشین کامپایل شوند.
مشکل این مدل هیبریدی این بود که اولین اجرای برنامه توسط کاربر (First Launch) همیشه کند و همراه با افت فریم بود، زیرا پروفایل عملکردی هنوز تشکیل نشده بود. اینجاست که Baseline Profiles به عنوان راه حل نهایی وارد میدان شد: توسعه دهنده کدهای داغ را در پروژه خود کشف و ثبت می کند تا کاربر حتی در همان اجرای اول، از سرعت کامپایل AOT بهره مند شود!
۲. تحلیل علمی زمان شروع اپلیکیشن (Cold vs Warm vs Hot Startup)
سیستم عامل اندروید سناریوهای شروع اپلیکیشن را به سه حالت دقیق تفکیک می کند:
- شروع سرد (Cold Start): فرآیند پروسس برنامه در حافظه رم وجود ندارد. سیستم عامل باید یک پروسس لینوکسی جدید از Zygote فورک کند، کلاس Application را بسازد، لودرهای تم و فونت را فعال نموده و اولین فریم اکتیویتی را رندر کند. بیس لاین پروفایل ها بیشترین تاثیر را دقیقا بر روی همین حالت دارند و زمان بالا آمدن را تا چند صد میلی ثانیه کوتاه می کنند.
- شروع گرم (Warm Start): پروسس برنامه همچنان در حافظه حضور دارد، اما اکتیویتی به دلیل کمبود رم از بین رفته است یا برنامه با فشردن دکمه Back بسته شده است. در این حالت نیازی به ساخت مجدد Application نیست اما ویوها باید بازسازی شوند.
- شروع داغ (Hot Start): پروسس و اکتیویتی هر دو در رم حضور دارند و کاربر صرفا اپلیکیشن را از پس زمینه به جلو می آورد. در این سناریو برنامه تقریبا بدون تاخیر نمایش داده می شود.
۳. راه اندازی ماژول Macrobenchmark و پلاگین Baseline Profile در گریدل
گوگل یک ماژول تستی اختصاصی و یک پلاگین گریدل خودکار به نام androidx.baselineprofile برای استخراج آسان این پروفایل ها تدارک دیده است. برای شروع، یک ماژول جدید از نوع Benchmark در اندروید استودیو ایجاد می کنیم:
// build.gradle.kts سطح ماژول اپلیکیشن (:app)
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.androidx.baselineprofile) // فعال سازی پلاگین بیس لاین پروفایل
}
dependencies {
// کتابخانه ران تایم برای رهگیری پروفایل در بیلد رلیز
implementation(libs.androidx.profileinstaller)
// ارتباط با ماژول بنچمارک
baselineProfile(project(":benchmark"))
}
سپس در فایل build.gradle.kts ماژول اختصاصی :benchmark تنظیمات زیر را اعمال می کنیم:
// build.gradle.kts سطح ماژول :benchmark
plugins {
alias(libs.plugins.android.test)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.androidx.baselineprofile)
}
android {
namespace = "ir.vahidhoseini.benchmark"
compileSdk = 35
defaultConfig {
minSdk = 28
targetSdk = 35
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
targetProjectPath = ":app"
experimentalProperties["android.experimental.self-instrumenting"] = true
}
dependencies {
implementation(libs.androidx.benchmark.macro.junit4)
implementation(libs.androidx.test.ext.junit)
implementation(libs.androidx.test.uiautomator)
}
۴. نگارش تست های خودکار استخراج پروفایل با BaselineProfileRule
برای اینکه کامپایلر بداند کدام مسیرها و متدها باید AOT کامپایل شوند، با استفاده از ابزار UI Automator یک سناریوی واقعی از رفتار کاربر (نظیر باز شدن اپ، ورود به صفحه خانه و اسکرول یک لیست) را کد نویسی می کنیم:
// BaselineProfileRule & UIAutomator
@RunWith(AndroidJUnit4::class)
class GenerateBaselineProfile {
@get:Rule
val baselineRule = BaselineProfileRule()
@Test
fun generateAppBaselineProfile() {
baselineRule.collect(
packageName = "ir.vahidhoseini.app",
maxIterations = 10
) {
// ۱. شروع سرد اپلیکیشن
pressHome()
startActivityAndWait()
// ۲. انتظار برای بارگذاری لیست مقالات
device.wait(Until.hasObject(By.res("article_feed_list")), 5_000)
// ۳. اسکرول برای ضبط متدهای رندرینگ کامپوز
val feedList = device.findObject(By.res("article_feed_list"))
feedList?.fling(Direction.DOWN)
device.waitForIdle()
// ۴. ورود به صفحه جزئیات و خروج
val firstArticle = device.findObject(By.res("article_item_card"))
firstArticle?.click()
device.wait(Until.hasObject(By.res("article_content_view")), 3_000)
device.pressBack()
}
}
}
۵. اجرای وظیفه گریدل و تولید فایل baseline-prof.txt
پس از اتصال یک دستگاه تست فیزیکی واقعی (نیازی به روت بودن نیست)، دستور جادویی گریدل را در ترمینال اجرا می کنیم:
./gradlew :app:generateBaselineProfile
پلاگین به طور خودکار بیلد Non-Minified Release را نصب کرده، سناریوهای حرکتی را شبیه سازی می کند و کدهای بایت کد لمس شده را در فایلی متنی به نام baseline-prof.txt در مسیر app/src/main/baseline-prof.txt ذخیره می نماید. محتوای این فایل شامل صدها امضای دکس شبیه نمونه زیر خواهد بود:
HSPLir/vahidhoseini/app/ui/HomeScreenKt;->HomeScreen(Landroidx/compose/runtime/Composer;I)V
HSPLir/vahidhoseini/app/data/repository/ArticleRepository;->getArticles()Lkotlinx/coroutines/flow/Flow;
HSPLandroidx/compose/foundation/lazy/LazyListKt;->LazyColumn(...)V
پیشوند H نشان دهنده متد داغ (Hot)، پیشوند S نشان دهنده اجرای در استارتاپ (Startup) و P نشان دهنده متد نیازمند پروفایل پیش کامپایل است.
۶. اندازه گیری و بنچمارک دقیق سرعت با MacrobenchmarkRule
چگونه مطمئن شویم این پروفایل واقعا سرعت اجرای برنامه ما را بالا برده است؟ با نوشتن یک بنچمارک مقایسه ای که دو حالت CompilationMode.None (بدون پروفایل) و CompilationMode.Partial(BaselineProfile) را ارزیابی می کند:
// MacrobenchmarkRule & CompilationMode
@RunWith(AndroidJUnit4::class)
class StartupBenchmarkTest {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun benchmarkStartupWithoutProfile() = measureStartup(CompilationMode.None())
@Test
fun benchmarkStartupWithBaselineProfile() = measureStartup(
CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require)
)
private fun measureStartup(mode: CompilationMode) {
benchmarkRule.measureRepeated(
packageName = "ir.vahidhoseini.app",
metrics = listOf(StartupTimingMetric()),
compilationMode = mode,
iterations = 15,
startupMode = StartupMode.COLD
) {
pressHome()
startActivityAndWait()
}
}
}
خروجی این تست بر روی دستگاه های میان رده و پرچمدار، کاهش چشمگیر زمان Time to Initial Display (TTID) را نشان می دهد:
- زمان شروع سرد بدون پروفایل (No Compilation): حدود ۸۴۰ میلیثانیه
- زمان شروع سرد با بیس لاین پروفایل (Baseline Profile AOT): حدود ۵۱۰ میلیثانیه (بهبود ۳۹ درصدی سرعت!)
۷. چرخه تعامل گوگل پلی با Cloud Profiles در نسخه نهایی
هنگامی که فایل باندل AAB را به کنسول توسعه دهندگان Google Play آپلود می کنید، گوگل فایل baseline-prof.txt را استخراج کرده و آن را با پروفایل های جمع آوری شده از سایر کاربران ترکیب می کند تا یک Cloud Profile قدرتمند تولید شود.
در نتیجه، به محض اینکه هر کاربری در دنیا اپلیکیشن را دانلود می کند، مارکت گوگل کدهای کامپایل شده متناسب با پردازنده گوشی آن فرد را ارسال می کند و برنامه از همان لحظه اول با نهایت سرعت ممکن اجرا می شود.
۸. جدول مقایسه حالات کامپایل کدهای اندروید در ماشین مجازی ART
جدول زیر شیوه های مختلف تبدیل کد در تاریخچه زمان اجرای اندروید را از منظر سرعت و زمان نصب مقایسه می نماید:
| ویژگی فنی و شاخص | مفسر خالص (Interpreter / JIT) | کامپایل کامل AOT (نسل قدیم) | بیس لاین پروفایل (Baseline Profiles) |
|---|---|---|---|
| سرعت اجرای اول (Cold Start) | کند (همراه با لگ های کامپایل حین اجرا) | بسیار بالا | بسیار بالا و بهینه (۳۰-۴۰٪ سریع تر) |
| زمان نصب اپلیکیشن توسط کاربر | آنی و بسیار سریع | بسیار طولانی و خسته کننده (چندین دقیقه) | بسیار سریع (تنها کدهای بحرانی کامپایل می شوند) |
| میزان فضای اشغال شده در هارد دیسک | کمترین مقدار (فقط بایت کد DEX) | بسیار زیاد (تمام باینری های بافر ذخیره می شدند) | کاملا متعادل و حساب شده |
| پشتیبانی از کتابخانه های کامپوز | مستعد لگ های سنگین فریم در اسکرول اول | خوب | بهترین حالت برای رندر نرم و حذف Jank کامپوز |
۱۰. تحلیل لاگ های Perfetto و پیگردی سیستم با Systrace
هنگامی که به دنبال چرایی تاخیر در شروع اپلیکیشن هستید، نگاه کردن به کدهای سطح بالا کافی نیست. ابزار Perfetto مانیتور سطح سیستم عامل اندروید است که رویدادهای هسته لینوکس، فعالیت هسته های CPU، زمان های توقف Garbage Collector و متدهای لایه زمان اجرای ART را با دقت نانوثانیه ضبط می کند:
# ضبط تریس سیستمی اجرای اپلیکیشن با اسکریپت رسمی perfetto
python record_android_trace -o app_startup.perfetto-trace -t 10s sched freq idle am wm gfx view binder_driver
با بارگذاری فایل تولید شده در سامانه ui.perfetto.dev، می توانید فازهای بحرانی شروع اپلیکیشن را مشاهده کنید:
- فاز bindApplication: زمان صرف شده برای بارگذاری فایل های کلاس و سازنده Application.
- فاز activityStart: زمان صرف شده برای لود تم ها و متد
onCreate(). - فاز inflate / Compose Initial Composition: ساخت اولین درخت رابط کاربری. با اعمال Baseline Profiles، زمان این بخش به دلیل تبدیل کدهای بایت کد به دستورات مستقیم ماشین تا نصف کاهش می یابد!
۱۱. بهینه سازی بارگذاری اولیه با کتابخانه AndroidX Startup
بسیاری از کتابخانه های جانبی (نظیر فایربیس، ورک منیجر یا ابزار های ردیابی کرش) از ContentProvider های پنهان برای اینیشیالایز خودکار در زمان استارتاپ استفاده می کنند. وجود چندین کانتنت پرووایدر زمان شروع سرد را به شدت افزایش می دهد. با استفاده از androidx.startup:
<!-- ادغام تمام اولیه سازها در یک Initializer مرکزی در مانیفست -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="ir.vahidhoseini.app.startup.TimberInitializer"
android:value="androidx.startup" />
</provider>
۱۲. چک لیست طلایی کاهش زمان شروع Cold Start برای پروداکشن
برای رسیدن به زمان شروع سرد زیر ۵۰۰ میلی ثانیه در محصولات بزرگ، رعایت اصول زیر الزامی است:
- تولید منظم Baseline Profiles: اطمینان از قرار داشتن فایل
baseline-prof.txtدر پوشهsrc/main. - پرهیز از کارهای بلاکینگ در Application.onCreate: تمامی درخواست های شبکه، دیتابیس و کارهای غیرفوری را با
CoroutineScope(Dispatchers.Default)به پس زمینه منتقل کنید. - Lazy Initialization وابستگی ها: نمونه سازی سرویس ها را تا لحظه اولین نیاز به تعویق بیندازید.
- فعال سازی R۸ Full Mode: کدهای بلااستفاده را حذف کرده و متدهای تک بار مصرف را Inlining نمایید.
۱۳. کالبدشکافی عمیق فرمت باینری DEX و تفاوت فازهای کامپایل در ART
فایل های کلاس کامپایل شده جاوا و کاتلین در قالب فایل های classes.dex بسته بندی می شوند. سیستم عامل اندروید در لایه زیرین زمان اجرای ART چندین شیوه برای اجرای این بایت کدها به کار می گیرد:
- فاز Verify (اعتبارسنجی بایت کد): بررسی امنیت نوع و عدم تجاوز از مرزهای حافظه. این فاز در زمان شروع برنامه بار پردازشی بالایی دارد. با کامپایل AOT، این فاز از قبل انجام شده و کاملا نادیده گرفته می شود.
- فاز Quickening: جایگزینی دستورات پیچیده دکس با دستورات مستقیم و ساده تر ماشین مجازی.
- فاز Profile-Guided Optimization (PGO): متدهایی که در فایل
baseline-prof.txtثبت شده اند، مستقیما به دستورات باینری پردازنده ARM۶۴ ترجمه می شوند و در یک فایل مجزا به نامbase.artوbase.odexدر دایرکتوری/data/app/.../oat/کش می گردند.
برای بررسی کدهای تولید شده توسط موتور ART و ممیزی کدهای کامپایل شده اپلیکیشن می توان از دستور قدرتمند oatdump روی شبیه ساز استفاده نمود:
adb shell oatdump --oat-file=/data/app/ir.vahidhoseini.app/oat/arm64/base.odex
۱۴. یکپارچه سازی پایپ لاین تولید Baseline Profile با گیت هاب اکشنز (CI/CD)
اجرای دستی دستور استخراج پروفایل ممکن است توسط توسعه دهندگان فراموش شود. بهترین الگو، خودکارسازی این فرآیند در خط لوله GitHub Actions با استفاده از یک شبیه ساز بدون رابط گرافیکی (Headless Android Emulator) است:
name: Generate Baseline Profile CI
on:
push:
branches: [ release/* ]
jobs:
generate-profile:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Run Baseline Profile Generation
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
target: google_apis
arch: x86_64
script: ./gradlew :app:generateBaselineProfile -Pandroid.testoptions.manageddevices.emulator.gpu=swiftshader_indirect
- name: Commit Updated Profile
run: |
git config --local user.name "Baseline CI Bot"
git add app/src/main/baseline-prof.txt
git commit -m "Auto-update Baseline Profiles via CI [skip ci]" || echo "No changes"
git push
۱۵. تحلیل شاخص های Play Console Android Vitals و تاثیر بر سئوی اپلیکیشن
گوگل پلی استور از شاخص های حیاتی (Android Vitals) به عنوان یکی از مهم ترین فاکتورهای رتبه بندی اپلیکیشن ها در نتایج جستجوی فروشگاه استفاده می کند. دو معیار بسیار حساس عبارتند از:
- نرخ شروع بسیار کند (Excessive Cold Start Rate): درصد کاربرانی که زمان شروع سرد برنامه آن ها بیش از ۵ ثانیه طول می کشد. اگر این نرخ از سقف مجاز گوگل (Bad Behavior Threshold که معمولا ۱.۵٪ تا ۲٪ است) عبور کند، گوگل پلی اپلیکیشن شما را در دسته بندی ها و کلمات کلیدی جریمه کرده و به کاربران هشدار می دهد!
- نرخ لکنت و پرش فریم (Slow Rendering & Frozen Frames): درصد جلساتی که بیش از ۵۰ درصد فریم ها با تاخیر مواجه می شوند.
اعمال منظم Baseline Profiles زمان شروع را به زیر ۱.۵ ثانیه رسانده و اپلیکیشن شما را در ناحیه سبز و امن Android Vitals تثبیت می کند که این امر به طور مستقیم به رشد رتبه ارگانیک برنامه در گوگل پلی می انجامد.
۱۶. بهینه سازی کدهای چندماژولار و ادغام پروفایل های ماژول های Feature
در پروژه هایی با ده ها ماژول، هر ماژول کتابخانه ای می تواند قوانین پروفایل اختصاصی خود را داشته باشد. با تنظیم androidx.baselineprofile در ماژول های فیچر، گریدل در هنگام ساخت بسته نصبی نهایی (AAB)، تمامی قوانین ماژول ها را با یکدیگر ادغام (Merge) کرده و یک پروفایل یکپارچه و بهینه تولید می نماید.
۱۷. تحلیل عمیق پرش فریم در کامپوز و رابطه مستقیم با کامپایل AOT
یکی از بزرگ ترین دلایل لگ در فریم های اولیه جت پک کامپوز، بارگذاری اولیه کلاس های درونی کامپایلر کامپوز (نظیر ComposerImpl و SlotTable) است.
هنگامی که کاربر برای اولین بار صفحه ای را باز می کند، اگر این متدها از قبل کامپایل نشده باشند، ماشین مجازی ART مجبور است همزمان با تلاش برای رندر ۶۰ یا ۱۲۰ فریم بر ثانیه، فرآیند JIT کامپایل را اجرا کند که این رقابت بر سر هسته های پردازنده مستقیما به بروز فریم های سوخته (Dropped Frames) منجر می شود.
با قرار دادن قوانین اسکرول و لود کامپوز در BaselineProfileRule، تمامی توابع کلیدی رندر کامپوز در زمان نصب برنامه پیش کامپایل می شوند و نرخ پرش فریم در اجرای اولیه تا ۹۵ درصد مهار می گردد.
۱۸. اسکریپت کامل مانیتورینگ عملکرد اجرای اپلیکیشن با Macrobenchmark
برای اجرای مداوم و استخراج معیارهای زمانی در محیط های محلی و تستی:
@Test
fun fullUserJourneyBenchmark() {
benchmarkRule.measureRepeated(
packageName = "ir.vahidhoseini.app",
metrics = listOf(
StartupTimingMetric(),
FrameTimingMetric() // سنجش زمان تاخیر رندر تک تک فریم ها
),
compilationMode = CompilationMode.Partial(BaselineProfileMode.Require),
iterations = 10,
startupMode = StartupMode.COLD
) {
pressHome()
startActivityAndWait()
// اسکرول آرام و شبیه سازی مطالعه مقالات
val recycler = device.findObject(By.res("article_feed_list"))
recycler?.setGestureMargin(device.displayWidth / 5)
repeat(3) {
recycler?.scroll(Direction.DOWN, 0.8f)
device.waitForIdle()
}
}
}
نتایج این بنچمارک ها نشان دهنده پایداری ۹۹ درصدی نرخ فریم بر ثانیه (P۹۹ Frame Time) زیر ۱۶ میلی ثانیه در دستگاه های اقتصادی و زیر ۸.۳ میلی ثانیه در نمایشگرهای ۱۲۰ هرتزی پرچمداران است.
۱۹. تحلیل رفتار مصرف باتری و مدیریت حرارتی (Thermal Throttling) با کامپایل AOT
فرآیند کامپایل در حین اجرا (JIT) و تفسیر کدهای بایت کد در لحظه استارتاپ، پردازنده دستگاه (CPU) را وادار می کند تا تمامی هسته های پرقدرت (Performance Cores) خود را در بالاترین فرکانس کاری فعال کند. این جهش ناگهانی بار پردازشی باعث افزایش لحظه ای مصرف انرژی باتری و بالا رفتن دمای چیپست می شود.
با پیاده سازی Baseline Profiles:
- به دلیل آماده بودن کدهای باینری ماشین، پردازنده نیازی به محاسبات سنگین ترجمه بایت کد ندارد.
- هسته های پردازنده در بازه زمانی بسیار کوتاه تری به وضعیت کم مصرف (Idle / Low Power State) بازمی گردند.
- تست های آزمایشگاهی نشان می دهد مصرف انرژی در فاز شروع اپلیکیشن تا ۲۲ درصد کاهش می یابد که این موضوع مانع از داغ شدن گوشی کاربر در استارتاپ های مداوم می گردد.
۲۰. راهنمای عیب یابی و ممیزی عدم اعمال Baseline Profiles
اگر پس از انتشار اپلیکیشن متوجه شدید که زمان استارتاپ بهبود نیافته است، چک لیست زیر را برای عیب یابی دنبال کنید:
- بررسی وجود profileinstaller در APK: با ابزار APK Analyzer در اندروید استودیو مطمئن شوید فایل های
assets/dexopt/baseline.profوassets/dexopt/baseline.profmدرون بیلد ریلیز حضور دارند. - بررسی نسخه اندروید دستگاه کاربر: بیس لاین پروفایل ها بر روی دستگاه های دارای اندروید ۷.۰ (API Level ۲۴) و بالاتر فعال می شوند. در نسخه های قدیمی تر، از سیستم کامپایل کامل AOT استفاده می شود.
- ارسال دستور دستی ادغام پروفایل در تست های محلی: برای وادار کردن سیستم عامل به کامپایل فوری پروفایل در تست های شبیه ساز:
سپس اپلیکیشن را مجددا باز کنید تا تفاوت چشمگیر سرعت اجرای کدها را بدون نیاز به ریبوت دستگاه ارزیابی نمایید.adb shell cmd package compile -m speed-profile -f ir.vahidhoseini.app
۲۱. کالبدشکافی فایل های باینری ODEX و VDEX در اندروید
در سیستم عامل اندروید، بسته به نسخه سیستم عامل، کدهای اجرایی پس از کامپایل در فایل های .vdex و .odex ذخیره می شوند. فایل VDEX حاوی کدهای دکس تایید شده است که نیازی به گذراندن مجدد مرحله Verify ندارند؛ در حالی که فایل ODEX حاوی کدهای کامپایل شده مستقیم پردازنده است.
بیس لاین پروفایل ها مستقیما ساختار فایل های ODEX را غنی می کنند تا پردازنده در اولین فراخوانی ها، به جای سرگردانی در حافظه مجازی، کدها را از حافظه کش L۱/L۲ پردازنده بدون تاخیر اجرا نماید.
۲۲. بهینه سازی کتابخانه های شخص ثالث و SDKهای تبلیغاتی
در بسیاری از اپ های بزرگ، بخش عمده ای از تاخیر شروع مربوط به کدهای خود توسعه دهنده نیست، بلکه به SDKهای شخص ثالث (نظیر آنالیتیکس، پنل های پوش نوتیفیکیشن یا شبکه های تبلیغاتی) مربوط می شود. با ایجاد متدهای آغازین تنبل (Lazy Initializers) و بارگذاری این سرویس ها پس از نمایش فریم اول (First Frame Render)، زمان پاسخگویی برنامه به طور چشمگیری بهبود می یابد.
۲۳. بهینه سازی بارگذاری فونت ها و منابع برداری (Vector Drawables) در شروع برنامه
یکی از گلوگاه های مخفی در افزایش زمان Cold Start، پارس کردن فایل های XML برداری سنگین و بارگذاری همزمان فونت های سفارشی از پوشه assets است. در معماری های پیشرفته اندروید:
- از ویژگی فونت های دانلودی (Downloadable Fonts) از طریق Google Play Services استفاده می شود تا حجم اولیه اپلیکیشن کاهش یافته و فونت ها در سطح سیستم عامل کش شوند.
- آیکون های برداری پیچیده با ابزار های بهینه ساز (مانند SVG to VectorDrawable پیشرفته) ساده سازی می شوند تا تعداد گره های مسیر (Path Nodes) به حداقل برسد.
- تعریف فونت ها در کامپوز با استفاده از
Font(resId, LoadingStrategy.Async)انجام می شود تا بارگذاری فونت ها ترد اصلی رندرینگ را قفل نکند.
۲۴. تنظیمات پیشرفته اجرای تست های بنچمارک بر روی دستگاه های روت نشده
هنگام اجرای بنچمارک بر روی شبیه ساز یا گوشی های تست شخصی، ممکن است با خطاهایی مبنی بر کمبود دقت به دلیل فعال بودن مکانیزم های ذخیره باتری یا قفل نبودن کلاک CPU مواجه شوید. برای اجرای پایدار تست ها می توان از آرگومان های تستی گریدل زیر بهره گرفت:
android {
defaultConfig {
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR,LOW-BATTERY"
}
}
اگرچه در تست های رسمی پروداکشن باید همیشه تست ها روی گوشی فیزیکی با شارژ بالای ۸۰ درصد و بدون قفل های نرم افزاری اجرا گردند تا دقیق ترین داده های آماری حاصل شوند.
تفاوت Baseline Profile با پیش کامپایل AOT کامل چیست؟
در پیش کامپایل کامل، تمام کدهای برنامه به بایت کد نیتیو تبدیل می شوند که فضای نصب را بسیار بالا می برد. اما بیس لاین پروفایل منحصراً متدها و کلاس های بحرانی مسیر استارتاپ و اسکرول را کامپایل می کند و حجم را بهینه نگه می دارد.
بیس لاین پروفایل چه تاثیری بر زمان شروع برنامه (Cold Start) دارد؟
طبق بنچمارک های رسمی گوگل، تولید بیس لاین پروفایل صحیح می تواند زمان Cold Start را بین ۳۰ تا ۴۰ درصد کاهش دهد و فریم های افتاده (Jank) در اسکرول اولیه را تا ۶۰ درصد حذف کند.
آیا تولید Baseline Profile برای بیلد Debug کاربرد دارد؟
خیر. بیس لاین پروفایل ها منحصرا برای بیلدهای Release و توزیع در پروداکشن طراحی شده اند. در محیط دیباگ، توسعه دهندگان نیاز به سرعت کامپایل فوری و اتصال سریع دیباگر دارند، بنابراین کامپایل AOT پیش از موعد در محیط های تستی غیرفعال است.
چند وقت یک بار باید Baseline Profile های پروژه را مجددا تولید کنیم؟
توصیه رسمی مهندسی این است که تسک generateBaselineProfile را در پایپ لاین های انتشار نهایی CI/CD (مثلا قبل از هر ریلیز اصلی به گوگل پلی یا بازار) قرار دهید تا با تغییر ساختار کدهای کاتلین، فایل پروفایل به روز بماند.
آیا بیس لاین پروفایل در اندرویدهای زیر نسخه ۷ (نوقا) کار می کند؟
خیر، فناوری پروفایلینگ بر پایه ساختار کامپایلر ART و ماژول Profile-Guided Optimization (PGO) است که از اندروید ۷ به بعد (API ۲۴) پشتیبانی می شود.
پروفایل استارتاپ چگونه به دست کاربر نهایی در گوگل پلی می رسد؟
هنگام ساخت Android App Bundle (AAB)، فایل های baseline.prof در داخل بسته قرار گرفته و گوگل پلی آن ها را در زمان نصب تحویل سیستم عامل کاربر می دهد.
آیا بیس لاین پروفایل مصرف رم دستگاه را افزایش می دهد؟
خیر، به دلیل اینکه کدهای کامپایل شده نیازی به پردازش تفسیری در مفسر ندارند، بار CPU و سربار تخصیص حافظه در زمان اجرا به شکل محسوسی کمتر می شود.
آیا بیس لاین پروفایل روی فریم ورک Jetpack Compose اثرگذار است؟
بله، بیشترین جهش کارایی بیس لاین پروفایل در کامپوز مشاهده می شود، زیرا کامپایلر کامپوز کدهای جنریت شده متعددی دارد که با پیش کامپایل، سرعت رندر اولیه تا دو برابر سریع تر می شود.
امتیاز و نظرات
هنوز نظری ثبت نشده است. اولین نفر باشید.