ایجاد «نمایه‌های مبنا»

Baseline Profiles برای به‌حداکثر رساندن عملکرد Jetpack Compose ضروری است. پیش‌کامپایل کردن مسیرهای قطعی کاربر کمک می‌کند مطمئن شوید که «رابط کاربری Compose» به‌طور روان ارائه می‌شود.

بااستفاده از کتابخانه Jetpack Macrobenchmark و BaselineProfileRule، به‌طور خودکار برای هر نسخه پخش برنامه نمایه ایجاد کنید. توصیه می‌کنیم از نسخه com.android.tools.build:gradle:8.0.0 یا بالاتر استفاده کنید تا هنگام استفاده از «نمایه‌های پایه» از بهبودهای ساخت بهره‌مند شوید.

مراحل کلی برای ایجاد یک «نمایه پایه» جدید به شرح زیر است:

  1. واحد «نمایه مبنا» را راه‌اندازی کنید.
  2. آزمون JUnit را که به تولید Baseline Profiles کمک می‌کند تعریف کنید.
  3. مسیرهای قطعی کاربر (CUJ) را که می‌خواهید بهینه‌سازی کنید اضافه کنید.
  4. «نمایه مبنا» را تولید کنید.

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

ایجاد Baseline Profile جدید با AGP نسخه ۸.۲ یا بالاتر

ساده‌ترین راه برای ایجاد یک نمایه پایه جدید، استفاده از الگوی ماژول نمایه پایه است که از Android Studio Iguana و Android Gradle Plugin (AGP) 8.2 دردسترس است.

الگوی واحد «تولیدکننده نمایه خط پایه» Android Studio ایجاد واحد جدید برای تولید و محک‌زنی «نمایه‌های خط پایه» را خودکارسازی می‌کند. اجرای الگو بیشتر پیکربندی ساخت معمول، تولید «نمایه پایه»، و کد درستی‌سنجی را تولید می‌کند. این الگو کدی برای تولید و محک‌زنی Baseline Profiles ایجاد می‌کند تا راه‌اندازی برنامه را اندازه‌گیری کند.

راه‌اندازی واحد «نمایه مبنا»

برای اجرای الگوی پیمانه «نمایه پایه»، این مراحل را دنبال کنید:

  1. فایل > جدید > ماژول جدید را انتخاب کنید.
  2. الگوی Baseline Profile Generator را در پانل Templates انتخاب کنید و آن را پیکربندی کنید:
    شکل ۱. الگوی واحد «تولیدکننده نمایه مبنا».
    فیلدهای موجود در الگو عبارتند از:
    • برنامه هدف: برنامه‌ای که Baseline Profile برای آن تولید شده است. وقتی فقط یک واحد برنامه در پروژه‌تان دارید، فقط یک مورد در این فهرست وجود دارد.
    • نام واحد: نامی که برای واحد «نمایه مبنا» درحال ایجاد می‌خواهید.
    • نام بسته: نام بسته‌ای که برای واحد Baseline Profile می‌خواهید.
    • زبان: اینکه می‌خواهید کد تولیدشده Kotlin باشد یا Java.
    • زبان پیکربندی ساخت: اینکه می‌خواهید از Kotlin Script (KTS)‎ یا Groovy برای دستورگان پیکربندی ساخت خود استفاده کنید.
    • استفاده از دستگاه تحت مدیریت Gradle: اینکه آیا از دستگاه‌های تحت مدیریت Gradle برای آزمایش برنامه‌تان استفاده می‌کنید یا نه.
  3. روی پایان کلیک کنید تا واحد جدید ایجاد شود. اگر از کنترل منبع استفاده می‌کنید، ممکن است از شما خواسته شود فایل‌های ماژول جدیداً ایجادشده را به کنترل منبع اضافه کنید.

تعریف تولیدکننده «نمایه مبنا»

واحد تازه ایجادشده حاوی آزمایش‌هایی برای تولید و محک‌زنی Baseline Profile و آزمایش کردن فقط راه‌اندازی پایه برنامه است. توصیه می‌کنیم این موارد را تقویت کنید تا شامل CUJ و گردش‌های کاری راه‌اندازی پیشرفته شود. مطمئن شوید که همه آزمایش‌های مربوط به راه‌اندازی برنامه در بلوک rule با includeInStartupProfile تنظیم‌شده روی true قرار دارند؛ برعکس، برای عملکرد بهینه مطمئن شوید که آزمایش‌های غیرمرتبط با راه‌اندازی برنامه در Startup Profile گنجانده نشده باشند. بهینه‌سازی‌های راه‌اندازی برنامه برای تعریف بخش خاصی از Baseline Profile به‌نام نمایه راه‌اندازی استفاده می‌شود.

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

تولید و نصب کردن «نمایه مبنا»

الگوی ماژول «نمایه مبنا» پیکربندی اجرای جدیدی برای تولید «نمایه مبنا» اضافه می‌کند. اگر از نسخه‌های ویژه محصول استفاده می‌کنید، «استودیو Android» چند پیکربندی اجرا ایجاد می‌کند تا بتوانید «نمایه‌های پایه» جداگانه‌ای برای هر نسخه ویژه تولید کنید.

پیکربندی اجرای «تولید نمایه مبنا».
شکل ۲. اجرای این پیکربندی «نمایه مبنا» را تولید می‌کند.

وقتی پیکربندی اجرای تولید نمایه پایه تکمیل می‌شود، نمایه پایه تولیدشده را در فایل src/variant/generated/baselineProfiles/baseline-prof.txt در ماژولی که درحال نمایه‌سازی است کپی می‌کند. گزینه‌های تنوع عبارتند از نوع ساخت نسخه پخش یا تنوع ساخت شامل نوع ساخت نسخه پخش.

«نمایه مبنا» تولیدشده دراصل در build/outputs ایجاد شده است. مسیر کامل توسط گونه یا نوع برنامه‌ای که نمایه می‌شود و اینکه آیا از دستگاه تحت مدیریت Gradle یا دستگاه متصل‌شده برای نمایه‌سازی استفاده می‌کنید، تعیین می‌شود. اگر از نام‌های استفاده‌شده توسط کد و پیکربندی‌های ساخت تولیدشده توسط الگو استفاده کنید، «نمایه Baseline» در فایل build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt ایجاد می‌شود. احتمالاً لازم نیست مستقیماً با این نسخه از «نمایه پایه» تولیدشده تعامل داشته باشید، مگراینکه آن را به‌طور دستی در پیمانه‌های هدف کپی کنید (توصیه نمی‌شود).

ایجاد Baseline Profile جدید با AGP 8.1

اگر نمی‌توانید از الگوی ماژول «نمایه مبنا» استفاده کنید، از الگوی ماژول Macrobenchmark و افزونه Gradle «نمایه مبنا» برای ایجاد «نمایه مبنا» جدید استفاده کنید. توصیه می‌کنیم از این ابزارها با شروع از Android Studio Giraffe و AGP 8.1 استفاده کنید.

در اینجا مراحل ایجاد «نمایه پایه» جدید بااستفاده از الگوی پیمانه Macrobenchmark و افزونه Baseline Profile Gradle آورده شده است:

  1. یک واحد Macrobenchmark در پروژه Gradle خود راه‌اندازی کنید.
  2. کلاس جدیدی به‌نام BaselineProfileGenerator تعریف کنید:

    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }
    

    تولیدکننده می‌تواند شامل تعاملاتی با برنامه شما فراتر از راه‌اندازی برنامه باشد. این کار به شما امکان می‌دهد عملکرد زمان اجرای برنامه‌تان را بهینه‌سازی کنید، مثلاً پیمایش فهرست‌ها، اجرای پویانمایی‌ها، و پیمایش در Activity. نمونه‌های دیگری از آزمایش‌هایی را ببینید که از @BaselineProfileRule برای بهبود مسیرهای قطعی کاربر استفاده می‌کنند.

  3. افزونه Baseline Profile Gradle را اضافه کنید (libs.plugins.androidx.baselineprofile). این افزونه تولید «نمایه‌های پایه» و نگهداری آن‌ها در آینده را آسان‌تر می‌کند.

  4. برای تولید «نمایه مبنا»، تکالیف Gradle :app:generateBaselineProfile یا :app:generateVariantBaselineProfile را در پایانه اجرا کنید.

    مولد را به‌عنوان آزمون ابزاری در دستگاه فیزیکی ریشه‌دار، شبیه‌ساز، یا دستگاه تحت مدیریت Gradle اجرا کنید. اگر از «دستگاه تحت مدیریت Gradle» استفاده می‌کنید، aosp را به‌عنوان systemImageSource تنظیم کنید، زیرا برای تولیدکننده «نمایه پایه» به دسترسی ریشه‌ای نیاز دارید.

    در پایان تکلیف تولید، «نمایه پایه» در app/src//generated/baselineProfiles کپی می‌شود.

ایجاد «نمایه پایه» جدید بدون الگو

توصیه می‌کنیم «نمایه مبنا» را بااستفاده از الگوی واحد نمایه مبنا در Android Studio (ترجیحاً) یا الگوی Macrobenchmark ایجاد کنید، اما می‌توانید از افزونه Gradle «نمایه مبنا» نیز به‌تنهایی استفاده کنید. برای مطالعه بیشتر درباره افزایه Baseline Profile Gradle، به پیکربندی تولید Baseline Profile مراجعه کنید.

در اینجا نحوه ایجاد Baseline Profile بااستفاده از افزونه Baseline Profile Gradle به‌طور مستقیم آورده شده است:

  1. ماژول com.android.test جدیدی ایجاد کنید—برای مثال، :baseline-profile.
  2. فایل build.gradle.kts را برای :baseline-profile پیکربندی کنید:

    1. افزایه androidx.baselineprofile را اعمال کنید.
    2. مطمئن شوید targetProjectPath به ماژول :app اشاره می‌کند.
    3. درصورت تمایل، دستگاه تحت مدیریت Gradle (GMD) اضافه کنید. در مثال زیر، pixel6Api31 است. اگر مشخص نشده باشد، افزونه از دستگاه متصل‌شده، چه شبیه‌سازی‌شده چه فیزیکی، استفاده می‌کند.
    4. پیکربندی موردنظرتان را همان‌طور که در مثال زیر نشان داده شده است اعمال کنید.

    کاتلین

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }

    شیک

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
  3. یک آزمایش «نمایه مبنا» در واحد آزمایشی :baseline-profile ایجاد کنید. مثال زیر آزمایشی است که Baseline Profile را برای راه‌اندازی برنامه تولید می‌کند.

        class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                uiAutomator { startApp(PACKAGE_NAME) }
            }
        )
    }
    
  4. فایل build.gradle.kts را در واحد برنامه به‌روز کنید، برای مثال :app.

    1. افزایه androidx.baselineprofile را اعمال کنید.
    2. وابستگی baselineProfile را به واحد :baseline-profile اضافه کنید.

    کاتلین

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }

    شیک

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile'
    }
  5. نمایه را با اجرای تکالیف Gradle :app:generateBaselineProfile یا :app:generateVariantBaselineProfile تولید کنید.

  6. در پایان تکلیف تولید، «نمایه پایه» در app/src/variant/generated/baselineProfiles کپی می‌شود.

محک زدن «نمایه مبنا»

برای محک‌زنی «نمایه پایه»، پیکربندی «اجرای آزمایش ابزاردار Android» جدیدی از کنش حاشیه ایجاد کنید که محک‌های تعریف‌شده در فایل StartupBenchmarks.kt را اجرا می‌کند. برای کسب اطلاعات بیشتر درباره آزمایش ارزیابی مقایسه‌ای، به ایجاد کلاس Macrobenchmark و ارزیابی مقایسه‌ای «نمایه‌های پایه» با کتابخانه Macrobenchmark مراجعه کنید.

شکل ۳.‏ اجرا کردن «آزمایش‌های Android» از کناره کنش.

وقتی این را در Android Studio اجرا می‌کنید، خروجی ساخت حاوی جزئیات بهبودهای سرعت است که Baseline Profile ارائه می‌دهد:

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

همه مسیرهای کد الزامی را ضبط کنید

دو سنجه کلیدی برای اندازه‌گیری زمان راه‌اندازی برنامه به شرح زیر است:

وقتی روش reportFullyDrawn از ComponentActivity فراخوانی شود، TTFD گزارش می‌شود. اگر reportFullyDrawn هرگز فراخوانی نشود، به‌جای آن TTID گزارش می‌شود. ممکن است لازم باشد زمان فراخوانی reportFullyDrawn را تا پس‌از تکمیل بارگیری ناهمگام به‌تأخیر بیندازید. برای مثال، اگر واسط کاربر حاوی فهرست تنبل پویا باشد، ممکن است فهرست توسط تکلیف پس‌زمینه‌ای پر شود که پس‌از اولین ترسیم فهرست و درنتیجه پس‌از اینکه واسط کاربر به‌عنوان کاملاً ترسیم‌شده علامت‌گذاری شد تکمیل می‌شود. در چنین مواردی، کدی که پس‌از رسیدن رابط کاربری به وضعیت کاملاً ترسیم‌شده اجرا می‌شود در «نمایه پایه» گنجانده نمی‌شود.

برای گنجاندن جمعیت فهرست به‌عنوان بخشی‌از «نمایه پایه»، FullyDrawnReporter را بااستفاده از getFullyDrawnReporter دریافت کنید و یک گزارش‌دهنده به آن در کد برنامه‌تان اضافه کنید. وقتی تکلیف پس‌زمینه پر کردن فهرست را تمام کرد، گزارش‌دهنده را رها کنید. FullyDrawnReporter تا زمانی که همه گزارش‌دهنده‌ها منتشر نشوند، روش reportFullyDrawn را فراخوانی نمی‌کند. با انجام این کار، «نمایه خط پایه» شامل مسیرهای کد موردنیاز برای پر کردن فهرست می‌شود. این کار رفتار برنامه را برای کاربر تغییر نمی‌دهد، اما به «نمایه پایه» اجازه می‌دهد همه مسیرهای کد لازم را دربرگیرد.

برای نشان دادن وضعیت کاملاً ترسیم‌شده، از میاناهای برنامه‌سازی کاربردی Compose زیر استفاده کنید:

  • ReportDrawn نشان می‌دهد که ترکیب‌پذیر شما بلافاصله برای تعامل آماده است.
  • ReportDrawnWhen گزاره‌ای مانند list.count > 0 را می‌گیرد تا نشان دهد چه زمانی ترکیب‌پذیر شما برای تعامل آماده است.
  • ‫ReportDrawnAfter یک روش تعلیق را اتخاذ می‌کند که وقتی تکمیل می‌شود، نشان می‌دهد که ترکیب‌پذیر شما برای تعامل آماده است.