बेसलाइन प्रोफ़ाइल बनाएं

Jetpack Compose की परफ़ॉर्मेंस को बेहतर बनाने के लिए, बेसलाइन प्रोफ़ाइलें ज़रूरी हैं. उपयोगकर्ता के अहम सफ़र को पहले से कंपाइल करने से, यह पक्का करने में मदद मिलती है कि आपका Compose UI आसानी से रेंडर हो.

Jetpack Macrobenchmark लाइब्रेरी और BaselineProfileRule का इस्तेमाल करके, ऐप्लिकेशन की हर रिलीज़ के लिए परफ़ॉर्मेंस प्रोफ़ाइलें अपने-आप जनरेट करें. हमारा सुझाव है कि आप com.android.tools.build:gradle:8.0.0 या इससे ऊपर के वर्शन का इस्तेमाल करें. नए वर्शन में बिल्ड में सुधार किए गए हैं. इनसे खास तौर पर बेसलाइन प्रोफ़ाइलें इस्तेमाल करते समय मदद मिलती है.

नई बेसलाइन प्रोफ़ाइल बनाने का सामान्य तरीका यहां दिया गया है:

  1. बेसलाइन प्रोफ़ाइल मॉड्यूल सेट अप करें.
  2. JUnit टेस्ट तय करें, ताकि बेसलाइन प्रोफ़ाइल जनरेट की जा सके.
  3. उन क्रिटिकल यूज़र जर्नी (सीयूजे) को जोड़ें जिन्हें ऑप्टिमाइज़ करना है.
  4. बेसलाइन प्रोफ़ाइल जनरेट करें.

बेसलाइन प्रोफ़ाइल जनरेट करने के बाद, किसी फ़िज़िकल डिवाइस का इस्तेमाल करके उसे बेंचमार्क करें ताकि स्पीड में हुए सुधारों को मापा जा सके.

AGP 8.2 या इसके बाद के वर्शन का इस्तेमाल करके नई बेसलाइन प्रोफ़ाइल बनाना

नई बेसलाइन प्रोफ़ाइल बनाने का सबसे आसान तरीका, बेसलाइन प्रोफ़ाइल मॉड्यूल टेंप्लेट का इस्तेमाल करना है. यह Android Studio Iguana और Android Gradle प्लगिन (AGP) 8.2 से उपलब्ध है.

Android Studio बेसलाइन प्रोफ़ाइल जनरेटर मॉड्यूल टेंप्लेट, नई मॉड्यूल बनाने की प्रोसेस को अपने-आप पूरा करता है. इससे, बेसलाइन प्रोफ़ाइलें जनरेट करने और उनको बेंचमार्क करने में मदद मिलती है. टेंप्लेट रन करने पर ज़्यादातर सामान्य बिल्ड कॉन्फ़िगरेशन, बेसलाइन प्रोफ़ाइल जनरेशन, और वेरिफिकेशन कोड अपने-आप जनरेट हो जाता है. यह टेंप्लेट, कोड बनाता है. इस कोड की मदद से, बेसलाइन प्रोफ़ाइल जनरेट की जाती हैं और उनको बेंचमार्क किया जाता है. इससे यह मापा जा सकता है कि ऐप्लिकेशन कितनी तेज़ी से स्टार्ट हो रहा है.

बेसलाइन प्रोफ़ाइल मॉड्यूल सेट अप करना

बेसलाइन प्रोफ़ाइल मॉड्यूल टेंप्लेट चलाने के लिए, यह तरीका अपनाएं:

  1. File > New > New Module को चुनें.
  2. टेंप्लेट पैनल में, बेसलाइन प्रोफ़ाइल जनरेटर टेंप्लेट चुनें और इसे कॉन्फ़िगर करें:
    पहली इमेज. बेसलाइन प्रोफ़ाइल जनरेटर मॉड्यूल टेंप्लेट.
    टेंप्लेट में ये फ़ील्ड होते हैं:
    • टारगेट ऐप्लिकेशन: वह ऐप्लिकेशन जिसके लिए बेसलाइन प्रोफ़ाइल जनरेट की गई है. अगर आपके प्रोजेक्ट में सिर्फ़ एक ऐप्लिकेशन मॉड्यूल है, तो इस सूची में सिर्फ़ एक आइटम होगा.
    • मॉड्यूल का नाम: यह उस बेसलाइन प्रोफ़ाइल मॉड्यूल का नाम है जिसे बनाया जा रहा है.
    • पैकेज का नाम: यह वह पैकेज का नाम है जो आपको बेसलाइन प्रोफ़ाइल मॉड्यूल के लिए चाहिए.
    • भाषा: जनरेट किया गया कोड Kotlin या Java में होना चाहिए.
    • बिल्ड कॉन्फ़िगरेशन की भाषा: आपको बिल्ड कॉन्फ़िगरेशन स्क्रिप्ट के लिए Kotlin Script (KTS) या Groovy का इस्तेमाल करना है या नहीं.
    • ऐसा डिवाइस इस्तेमाल करें जिसे Gradle मैनेज करता है: अगर आपको अपने ऐप्लिकेशन की जांच करने के लिए, ऐसे डिवाइसों का इस्तेमाल करना है जिन्हें Gradle मैनेज करता है.
  3. खत्म करें पर क्लिक करें. इसके बाद, नया मॉड्यूल बन जाएगा. अगर सोर्स कंट्रोल का इस्तेमाल किया जा रहा है, तो आपको नई बनाई गई मॉड्यूल फ़ाइलों को सोर्स कंट्रोल में जोड़ने के लिए कहा जा सकता है.

बेसलाइन प्रोफ़ाइल जनरेटर तय करना

नए मॉड्यूल में, बेसलाइन प्रोफ़ाइल जनरेट करने और बेंचमार्क करने के लिए टेस्ट शामिल होते हैं. इसके साथ-साथ, बुनियादी तौर पर यह भी मापा जा सकता है कि ऐप्लिकेशन कितनी तेज़ी से स्टार्ट हो रहा है. हमारा सुझाव है कि आप इनमें सीयूजे और स्टार्टअप के बेहतर वर्कफ़्लो शामिल करें. पक्का करें कि ऐप्लिकेशन के शुरू होने से जुड़े सभी टेस्ट, rule ब्लॉक में हों और includeInStartupProfile को true पर सेट किया गया हो. इसके उलट, सबसे अच्छी परफ़ॉर्मेंस के लिए पक्का करें कि स्टार्टअप प्रोफ़ाइल में ऐसे टेस्ट शामिल न हों जो ऐप्लिकेशन के शुरू होने से नहीं जुड़े हैं. ऐप्लिकेशन के शुरू होने के ऑप्टिमाइज़ेशन का इस्तेमाल, बेसलाइन प्रोफ़ाइल के एक खास हिस्से को तय करने के लिए किया जाता है. इसे स्टार्टअप प्रोफ़ाइल कहा जाता है.

अगर इन सीयूजे को जनरेट की गई बेसलाइन प्रोफ़ाइल और बेंचमार्क कोड से अलग किया जाता है, तो इनका रखरखाव आसान हो जाता है. ऐसा इसलिए, ताकि इनका इस्तेमाल दोनों के लिए किया जा सके. इसका मतलब है कि आपके सीयूजे में किए गए बदलावों का लगातार इस्तेमाल किया जाता है.

बेसलाइन प्रोफ़ाइल जनरेट करना और उसे इंस्टॉल करना

बेसलाइन प्रोफ़ाइल मॉड्यूल टेंप्लेट, बेसलाइन प्रोफ़ाइल जनरेट करने के लिए एक नया रन कॉन्फ़िगरेशन जोड़ता है. अगर ऐप्लिकेशन टाइप का इस्तेमाल किया जाता है, तो Android Studio कई रन कॉन्फ़िगरेशन बनाता है. इससे हर फ़्लेवर के लिए अलग-अलग बेसलाइन प्रोफ़ाइल जनरेट की जा सकती हैं.

बेसलाइन प्रोफ़ाइल जनरेट करने वाला रन कॉन्फ़िगरेशन.
दूसरी इमेज. इस कॉन्फ़िगरेशन को चलाने पर, बेसलाइन प्रोफ़ाइल जनरेट होती है.

जनरेट बेसलाइन प्रोफ़ाइल रन कॉन्फ़िगरेशन पूरा होने पर, यह जनरेट की गई बेसलाइन प्रोफ़ाइल को, प्रोफ़ाइल किए जा रहे मॉड्यूल की src/variant/generated/baselineProfiles/baseline-prof.txt फ़ाइल में कॉपी करता है. वैरिएंट के विकल्प या तो रिलीज़ के लिए तैयार बिल्ड होते हैं या ऐसे बिल्ड वैरिएंट होते हैं जिसमें रिलीज़ के लिए तैयार बिल्ड शामिल हो.

जनरेट की गई बेसलाइन प्रोफ़ाइल, मूल रूप से build/outputs में बनाई गई है. पूरा पाथ, प्रोफ़ाइल किए जा रहे ऐप्लिकेशन के वैरिएंट या फ़्लेवर के हिसाब से तय होता है. साथ ही, यह भी तय होता है कि प्रोफ़ाइलिंग के लिए, ऐसे डिवाइस का इस्तेमाल किया जा रहा है जिसे Gradle मैनेज करता है या कनेक्ट किए गए डिवाइस का. अगर कोड और टेंप्लेट से जनरेट किए गए बिल्ड कॉन्फ़िगरेशन के नामों का इस्तेमाल किया जाता है, तो बेसलाइन प्रोफ़ाइल build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt फ़ाइल में बनाई जाती है. आपको जनरेट की गई इस बेसलाइन प्रोफ़ाइल के वर्शन के साथ सीधे तौर पर इंटरैक्ट करने की ज़रूरत नहीं होगी. ऐसा तब तक नहीं होगा, जब तक कि इसे टारगेट मॉड्यूल में मैन्युअल तरीके से कॉपी न किया जाए. हालांकि, ऐसा करने का सुझाव नहीं दिया जाता.

AGP 8.1 की मदद से नई बेसलाइन प्रोफ़ाइल बनाना

अगर बेसलाइन प्रोफ़ाइल मॉड्यूल टेंप्लेट का इस्तेमाल नहीं किया जा सकता, तो नई बेसलाइन प्रोफ़ाइल बनाने के लिए, Macrobenchmark मॉड्यूल टेंप्लेट और बेसलाइन प्रोफ़ाइल Gradle प्लगिन का इस्तेमाल करें. हमारा सुझाव है कि आप इन टूल का इस्तेमाल Android Studio Giraffe और AGP 8.1 से शुरू करें.

Macrobenchmark मॉड्यूल टेंप्लेट और बेसलाइन प्रोफ़ाइल Gradle प्लगिन का इस्तेमाल करके, नई बेसलाइन प्रोफ़ाइल बनाने का तरीका यहां दिया गया है:

  1. अपने Gradle प्रोजेक्ट में Macrobenchmark मॉड्यूल सेट अप करें.
  2. BaselineProfileGenerator नाम की नई क्लास तय करें:

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

    जनरेटर में, ऐप्लिकेशन के स्टार्टअप के अलावा, ऐप्लिकेशन के साथ हुए अन्य इंटरैक्शन भी शामिल हो सकते हैं. इससे आपको अपने ऐप्लिकेशन की रनटाइम परफ़ॉर्मेंस को ऑप्टिमाइज़ करने में मदद मिलती है. जैसे, स्क्रोल करने वाली सूचियां, ऐनिमेशन चलाना, और किसी Activity में नेविगेट करना. क्रिटिकल यूज़र जर्नी को बेहतर बनाने के लिए, @BaselineProfileRule का इस्तेमाल करने वाले टेस्ट के अन्य उदाहरण देखें.

  3. बेसलाइन प्रोफ़ाइल Gradle प्लगिन (libs.plugins.androidx.baselineprofile) जोड़ें. इस प्लगिन की मदद से, बेसलाइन प्रोफ़ाइल जनरेट करना और उन्हें आने वाले समय में बनाए रखना आसान हो जाता है.

  4. बेसलाइन प्रोफ़ाइल जनरेट करने के लिए, टर्मिनल में :app:generateBaselineProfile या :app:generateVariantBaselineProfile Gradle टास्क चलाएं.

    जनरेटर को रूट किए गए फ़िज़िकल डिवाइस, एम्युलेटर या ऐसा डिवाइस जिसे Gradle मैनेज करता है पर, इंस्ट्रुमेंटेड टेस्ट के तौर पर चलाएं. अगर ऐसे डिवाइस का इस्तेमाल किया जाता है जिसे Gradle मैनेज करता है, तो aosp को systemImageSource के तौर पर सेट करें. ऐसा इसलिए, क्योंकि बेसलाइन प्रोफ़ाइल जनरेटर के लिए रूट ऐक्सेस की ज़रूरत होती है.

    जनरेट करने का टास्क पूरा होने के बाद, बेसलाइन प्रोफ़ाइल को app/src//generated/baselineProfiles में कॉपी कर दिया जाता है.

टेंप्लेट के बिना नई बेसलाइन प्रोफ़ाइल बनाना

हमारा सुझाव है कि Android Studio के बेसलाइन प्रोफ़ाइल मॉड्यूल टेंप्लेट (सुझाया गया) या Macrobenchmark टेंप्लेट का इस्तेमाल करके, बेसलाइन प्रोफ़ाइल बनाएं. हालांकि, बेसलाइन प्रोफ़ाइल Gradle प्लगिन का इस्तेमाल भी किया जा सकता है. बेसलाइन प्रोफ़ाइल Gradle प्लगिन के बारे में ज़्यादा जानने के लिए, बेसलाइन प्रोफ़ाइल जनरेट करने की सुविधा कॉन्फ़िगर करना लेख पढ़ें.

यहां सीधे तौर पर, बेसलाइन प्रोफ़ाइल Gradle प्लगिन का इस्तेमाल करके बेसलाइन प्रोफ़ाइल बनाने का तरीका बताया गया है:

  1. नया com.android.test मॉड्यूल बनाएं. उदाहरण के लिए, :baseline-profile.
  2. :baseline-profile के लिए build.gradle.kts फ़ाइल को कॉन्फ़िगर करें:

    1. androidx.baselineprofile प्लगिन लागू करें.
    2. पक्का करें कि targetProjectPath, :app मॉड्यूल पर ले जाता हो.
    3. इसके अलावा, ऐसा डिवाइस जिसे Gradle मैनेज करता है (जीएमडी) को भी जोड़ा जा सकता है. यहां दिए गए उदाहरण में, यह pixel6Api31 है. अगर इसे तय नहीं किया गया है, तो प्लगिन कनेक्ट किए गए डिवाइस का इस्तेमाल करता है. यह डिवाइस, एम्युलेट किया गया या फ़िज़िकल हो सकता है.
    4. अपनी पसंद का कॉन्फ़िगरेशन लागू करें. इसके लिए, यहां दिया गया उदाहरण देखें.

    Kotlin

    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
    }

    Groovy

    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 टेस्ट मॉड्यूल में, बेसलाइन प्रोफ़ाइल टेस्ट बनाएं. यहां एक टेस्ट का उदाहरण दिया गया है. इसमें ऐप्लिकेशन के शुरू होने की बेसलाइन प्रोफ़ाइल जनरेट की जाती है.

        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. :baseline-profile मॉड्यूल में baselineProfile डिपेंडेंसी जोड़ें.

    Kotlin

    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"))
    }

    Groovy

    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. :app:generateBaselineProfile या :app:generateVariantBaselineProfile Gradle टास्क चलाकर, प्रोफ़ाइल जनरेट करें.

  6. जनरेट करने का टास्क पूरा होने के बाद, बेसलाइन प्रोफ़ाइल को app/src/variant/generated/baselineProfiles में कॉपी कर दिया जाता है.

बेसलाइन प्रोफ़ाइल को बेंचमार्क करना

अपनी बेसलाइन प्रोफ़ाइल की तुलना करने के लिए, गटर ऐक्शन से नया Android इंस्ट्रुमेंटेड टेस्ट रन कॉन्फ़िगरेशन बनाएं. यह कॉन्फ़िगरेशन, StartupBenchmarks.kt फ़ाइल में तय किए गए बेंचमार्क को लागू करता है. बेंचमार्क टेस्टिंग के बारे में ज़्यादा जानने के लिए, Macrobenchmark क्लास बनाना और Macrobenchmark लाइब्रेरी की मदद से बेसलाइन प्रोफ़ाइल की परफ़ॉर्मेंस का आकलन करना लेख पढ़ें.

तीसरी इमेज. गटर ऐक्शन से Android टेस्ट चलाएं.

Android Studio में इस कमांड को चलाने पर, बिल्ड आउटपुट में उन सुधारों की जानकारी शामिल होती है जो बेसलाइन प्रोफ़ाइल से मिलते हैं:

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

सभी ज़रूरी कोड पाथ कैप्चर करें

ऐप्लिकेशन के शुरू होने में लगने वाले समय को मापने के लिए, ये दो मुख्य मेट्रिक इस्तेमाल की जाती हैं:

ComponentActivity के reportFullyDrawn तरीके को कॉल करने के बाद, टीटीएफ़डी की रिपोर्ट की जाती है. अगर reportFullyDrawn को कभी कॉल नहीं किया जाता है, तो इसके बजाय टीटीआईडी की रिपोर्ट की जाती है. आपको reportFullyDrawn को तब तक कॉल नहीं करना चाहिए, जब तक कि एसिंक्रोनस लोडिंग पूरी न हो जाए. उदाहरण के लिए, अगर यूज़र इंटरफ़ेस (यूआई) में डाइनैमिक लेज़ी लिस्ट है, तो हो सकता है कि लिस्ट को बैकग्राउंड टास्क से भरा गया हो. यह टास्क, लिस्ट के पहली बार दिखने के बाद पूरा होता है. इसलिए, यूज़र इंटरफ़ेस (यूआई) को पूरी तरह से दिखने के तौर पर मार्क करने के बाद पूरा होता है. ऐसे मामलों में, यूज़र इंटरफ़ेस (यूआई) के पूरी तरह से रेंडर होने के बाद चलने वाला कोड, बेसलाइन प्रोफ़ाइल में शामिल नहीं होता.

लिस्ट में शामिल लोगों की जानकारी को अपनी बेसलाइन प्रोफ़ाइल में शामिल करने के लिए, getFullyDrawnReporter का इस्तेमाल करके FullyDrawnReporter पाएं. इसके बाद, अपने ऐप्लिकेशन कोड में जाकर, इसमें एक रिपोर्टर जोड़ें. बैकग्राउंड टास्क के पूरा होने के बाद, रिपोर्टर को रिलीज़ करें. सभी रिपोर्टर के रिलीज़ होने तक, FullyDrawnReporter, reportFullyDrawn तरीके को कॉल नहीं करता. ऐसा करने से, बेसलाइन प्रोफ़ाइल में लिस्ट को भरने के लिए ज़रूरी कोड पाथ शामिल हो जाते हैं. इससे उपयोगकर्ता के लिए ऐप्लिकेशन के व्यवहार में कोई बदलाव नहीं होता. हालांकि, इससे बेसलाइन प्रोफ़ाइल में सभी ज़रूरी कोड पाथ शामिल किए जा सकते हैं.

पूरी तरह से ड्रॉ किए गए स्टेट को दिखाने के लिए, इन Compose API का इस्तेमाल करें:

  • ReportDrawn से पता चलता है कि आपका कंपोज़ेबल, तुरंत इंटरैक्ट करने के लिए तैयार है.
  • ReportDrawnWhen, list.count > 0 जैसे प्रेडिकेट लेता है, ताकि यह पता चल सके कि आपका कंपोज़ेबल इंटरैक्शन के लिए कब तैयार है.
  • ReportDrawnAfter एक सस्पेंडिंग तरीके का इस्तेमाल करता है. जब यह पूरा हो जाता है, तो इससे पता चलता है कि आपका कंपोज़ेबल इंटरैक्शन के लिए तैयार है.