R8 की मदद से ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करना

बेहतर उपयोगकर्ता अनुभव देने के लिए, आपको अपने ऐप्लिकेशन को ऑप्टिमाइज़ करना चाहिए, ताकि वह कम से कम साइज़ का हो और तेज़ी से काम करे. हमारा ऐप्लिकेशन ऑप्टिमाइज़र, R8, आपके ऐप्लिकेशन को इन तरीकों से बेहतर बनाता है: इस्तेमाल न किए गए कोड और संसाधनों को हटाकर, रनटाइम परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए कोड को फिर से लिखकर, और अन्य तरीकों से. आपके उपयोगकर्ताओं के लिए इसका मतलब यह है कि:

  • तेजी से शुरू कर सकते हैं
  • मेमोरी का कम इस्तेमाल
  • रेंडरिंग और रनटाइम परफ़ॉर्मेंस को बेहतर बनाया गया है
  • कम ANR

R8 ऑप्टिमाइज़ेशन के बारे में खास जानकारी

R8, ऐप्लिकेशन के साइज़ और स्पीड को ऑप्टिमाइज़ करने के लिए, कई चरणों वाली प्रोसेस का इस्तेमाल करता है. मुख्य ऑपरेशन में ये शामिल हैं:

  • कोड छोटा करना (इसे ट्री शेकिंग भी कहा जाता है): R8, आपके ऐप्लिकेशन और उसकी लाइब्रेरी डिपेंडेंसी से ऐसे कोड की पहचान करता है जिसे ऐक्सेस नहीं किया जा सकता. इसके बाद, उसे हटा देता है. R8, आपके ऐप्लिकेशन के एंट्री पॉइंट (जैसे, मेनिफ़ेस्ट में तय किया गया Activities या Services) का विश्लेषण करके, रेफ़र किए गए कोड का ग्राफ़ बनाता है. साथ ही, यह उन सभी कोड को हटा देता है जिन्हें रेफ़र नहीं किया गया है.

  • लॉजिकल ऑप्टिमाइज़ेशन: R8 आपके कोड को फिर से लिखता है, ताकि उसे बेहतर तरीके से लागू किया जा सके और ओवरहेड कम किया जा सके. मुख्य तकनीकों में ये शामिल हैं:

    • मेथड इनलाइनिंग: R8, किसी मेथड कॉल साइट को कॉल किए गए मेथड के असल कोड से बदल देता है. इससे फ़ंक्शन कॉल का ओवरहेड कम हो जाता है और R8 को आगे ऑप्टिमाइज़ेशन करने में मदद मिलती है.

    • क्लास मर्ज करना: R8, क्लास और इंटरफ़ेस के सेट को एक क्लास में जोड़ता है. इससे ऐप्लिकेशन में क्लास की संख्या कम हो जाती है. इससे मेमोरी पर दबाव कम होता है और ऐप्लिकेशन के शुरू होने की स्पीड बेहतर होती है.

  • कोड को उलझाना (इसे काट-छांट करना भी कहा जाता है): DEX फ़ाइल का साइज़ कम करने के लिए, R8 क्लास, फ़ील्ड, और मेथड के नामों को छोटा कर देता है. उदाहरण के लिए, com.example.MyActivity को a.b.a में बदला जा सकता है.

Android Gradle प्लगिन (AGP) के 8.12.0 वर्शन के बाद से, R8 भी ऑप्टिमाइज़ेशन के चरणों के दौरान संसाधनों को ऑप्टिमाइज़ करता है. ज़्यादा जानकारी के लिए, ऑप्टिमाइज़ किया गया रिसॉर्स श्रिंकिंग देखें.

ऑप्टिमाइज़ेशन की सुविधा चालू करना

अपने ऐप्लिकेशन के लिए ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने के लिए, अपने प्रोजेक्ट के AGP वर्शन के आधार पर सही डीएसएल का इस्तेमाल करें. हमारा सुझाव है कि ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा को सिर्फ़ ऐप्लिकेशन के उस फ़ाइनल वर्शन में चालू करें जिसे पब्लिश करने से पहले टेस्ट किया जाता है. आम तौर पर, यह रिलीज़ बिल्ड होता है. ऐसा इसलिए, क्योंकि ऑप्टिमाइज़ेशन की वजह से आपके प्रोजेक्ट को बिल्ड होने में ज़्यादा समय लगता है. साथ ही, कोड में बदलाव करने के तरीके की वजह से डीबग करना मुश्किल हो सकता है.

AGP के 9.3 और इसके बाद के वर्शन के लिए

AGP 9.3 और इसके बाद के वर्शन के लिए, ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने के लिए:

  • रिलीज़ बिल्ड की ऐप्लिकेशन-लेवल की बिल्ड स्क्रिप्ट में, optimization ब्लॉक में enable = true सेट करें.
  • src/<variant>/keepRules सोर्स सेट में, .keep सफ़िक्स वाली फ़ाइल में कीप नियम जोड़ें. उदाहरण के लिए, src/main/keepRules/custom-rules.keep.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

AGP के 9.3 से पहले के वर्शन के लिए लेगसी डीएसएल

ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने के लिए, रिलीज़ के लिए तैयार बिल्ड की ऐप्लिकेशन-लेवल की बिल्ड स्क्रिप्ट में, isMinifyEnabled = true (कोड ऑप्टिमाइज़ेशन के लिए) और isShrinkResources = true (संसाधन ऑप्टिमाइज़ेशन के लिए) सेट करें. हमारा सुझाव है कि आप हमेशा दोनों सेटिंग चालू रखें.

लेगसी डीएसएल (Kotlin)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            isMinifyEnabled = true

            // Enables resource shrinking.
            isShrinkResources = true

            proguardFiles(
                // Default file with automatically generated optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                ...
            )
            ...
        }
    }
    ...
}

लेगसी डीएसएल (ग्रूवी)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            minifyEnabled = true

            // Enables resource shrinking.
            shrinkResources = true

            // Default file with automatically generated optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')

            ...
        }
    }
}

R8 ऑप्टिमाइज़ेशन को बेहतर बनाना

R8 की परफ़ॉर्मेंस के फ़ायदे, सीधे तौर पर इस बात से जुड़े होते हैं कि R8 आपके कोडबेस को कितना ऑप्टिमाइज़ कर पाता है. R8 का ज़्यादा से ज़्यादा फ़ायदा पाने के लिए, सबसे सही तरीके अपनाएं:

'कीप रूल' को बेहतर बनाने के लिए, R8 Configuration Analyzer का इस्तेमाल करें.

R8 कॉन्फ़िगरेशन ऐनलिसिस टूल की मदद से ये काम किए जा सकते हैं:

  • R8 Configuration Analyzer रिपोर्ट में दी गई मेट्रिक को मॉनिटर करके, R8 कॉन्फ़िगरेशन की क्वालिटी को ट्रैक करें और उसे बेहतर बनाएं.
  • डेटा को सुरक्षित रखने से जुड़े सबसे सामान्य नियम ढूंढें. ये ऐसे नियम होते हैं जिनकी वजह से ऑप्टिमाइज़ेशन नहीं हो पाता
  • और यह समझें कि वे किस तरह के ऑप्टिमाइज़ेशन को रोकते हैं, ताकि उन्हें बेहतर बनाया जा सके.

R8 Configuration Analyzer, AGP के वर्शन 9.3.0-alpha05 या R8 के वर्शन 9.3.7-dev में उपलब्ध है. ज़्यादा जानकारी के लिए, R8 कॉन्फ़िगरेशन का विश्लेषण करना लेख पढ़ें.

छोटे ऐप्लिकेशन के लिए भी, इस्तेमाल नहीं किए जाने वाले रिसॉर्स को हटाने की प्रोसेस ऑप्टिमाइज़ करने की सुविधा

AGP के 8.12.0 वर्शन में, इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा जोड़ी गई है. इसका मकसद, रिसॉर्स और कोड ऑप्टिमाइज़ेशन को इंटिग्रेट करना है, ताकि कम जगह लेने वाले और तेज़ी से काम करने वाले ऐप्लिकेशन बनाए जा सकें. ऑप्टिमाइज़ किए गए संसाधन को छोटा करने की सुविधा से पहले, Android ऐसेट पैकेजिंग टूल (AAPT2) ऐसे नियम जनरेट करता था जो संसाधन को छोटा करने की सुविधा को कोड से अलग तरीके से इस्तेमाल करते थे. इससे अक्सर ऐसे कोड या संसाधन बने रहते थे जिन्हें ऐक्सेस नहीं किया जा सकता था और जो एक-दूसरे को रेफ़रंस करते थे.

इस्तेमाल नहीं किए जाने वाले रिसॉर्स को हटाने की प्रोसेस ऑप्टिमाइज़ करने की सुविधा की मदद से, रिसॉर्स को प्रोग्राम कोड का हिस्सा माना जाता है. इससे रेफ़रंस ग्राफ़ बनता है. जब कोड या संसाधनों के किसी कलेक्शन का रेफ़रंस नहीं दिया जाता है, तो उसे निजी डेटा के रखरखाव के नियम के तहत सुरक्षित नहीं रखा जाता. इसलिए, उसे हटाया जा सकता है.

इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा चालू करना

AGP 8.12 या 8.13 के लिए, ऑप्टिमाइज़ की गई नई रिसोर्स श्रिंकिंग पाइपलाइन चालू करने के लिए, अपने प्रोजेक्ट की gradle.properties फ़ाइल में यह कोड जोड़ें:

android.r8.optimizedResourceShrinking=true

अगर AGP 9.0.0 या इसके बाद के वर्शन का इस्तेमाल किया जा रहा है, तो आपको android.r8.optimizedResourceShrinking=true सेट करने की ज़रूरत नहीं है. इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा, आपके बिल्ड कॉन्फ़िगरेशन में isShrinkResources = true चालू होने पर अपने-आप लागू हो जाती है.

R8 ऑप्टिमाइज़ेशन सेटिंग की पुष्टि करना और उन्हें कॉन्फ़िगर करना

R8 को ऑप्टिमाइज़ेशन की पूरी सुविधाओं का इस्तेमाल करने की अनुमति देने के लिए, अपने प्रोजेक्ट की gradle.properties फ़ाइल से यह लाइन हटाएं. अगर यह लाइन मौजूद नहीं है, तो इसे जोड़ने की ज़रूरत नहीं है:

android.enableR8.fullMode=false

ध्यान दें कि ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने पर, स्टैक ट्रेस को समझना मुश्किल हो जाता है. ऐसा खास तौर पर तब होता है, जब R8 क्लास या तरीके के नामों को बदल देता है. अपने सोर्स कोड से सही तरीके से मेल खाने वाले स्टैक ट्रेस पाने के लिए, ओरिजनल स्टैक ट्रेस वापस पाना लेख पढ़ें.

अगर R8 चालू है, तो आपको स्टार्टअप की परफ़ॉर्मेंस को और बेहतर बनाने के लिए, स्टार्टअप प्रोफ़ाइलें बनानी चाहिए.

अगर ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने पर गड़बड़ियां होती हैं, तो उन्हें ठीक करने के लिए यहां कुछ रणनीतियां दी गई हैं:

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

AGP और R8 के वर्शन के व्यवहार में बदलाव

यहां दी गई टेबल में, Android Gradle प्लगिन (AGP) और R8 कंपाइलर के अलग-अलग वर्शन में जोड़ी गई मुख्य सुविधाओं के बारे में बताया गया है.

AGP का वर्शन नई सुविधाएं
9.3 आसान डीएसएल:नया `optimization {}` ब्लॉक, कम कॉन्फ़िगरेशन की सुविधा देता है. इसमें इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा हमेशा चालू रहती है. साथ ही, Android के डिफ़ॉल्ट कीप रूल से ऑप्ट-आउट किया जा सकता है.

`keepRules` सोर्स सेट: अगर नए डीएसएल का इस्तेमाल किया जा रहा है, तो आपको अपने कीप नियमों को src/<variant>/keepRules सोर्स सेट में रखना होगा. साथ ही, फ़ाइलों के नाम में .keep सफ़िक्स जोड़ना होगा. सोर्स सेट, लेगसी डीएसएल के साथ भी काम करते हैं.

केएमपी (Kotlin MultiPlatform) के इस्तेमाल से जुड़े नियम: केएमपी के लिए अब publish = true सेट करने की ज़रूरत नहीं है. साथ ही, यह .keep एक्सटेंशन के साथ src/<variant>/keepRules सोर्स सेट के साथ काम करता है.

ध्यान दें कि लेगसी डीएसएल अब भी काम करता है.
9.1 डिफ़ॉल्ट रूप से रीपैकेज की गई क्लास: R8, क्लास को रीपैकेज करता है. इसके लिए, वह उन्हें टॉप लेवल पर मौजूद बिना नाम वाले पैकेज में ले जाता है, ताकि DEX को और छोटा किया जा सके. इससे -repackageclasses विकल्प को तय करने की ज़रूरत नहीं पड़ती. यह सुविधा कैसे काम करती है और इससे ऑप्ट आउट करने का तरीका जानने के लिए, ग्लोबल विकल्प देखें.
9.0 इस्तेमाल नहीं किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा: यह डिफ़ॉल्ट रूप से चालू होती है. इसे android.r8.optimizedResourceShrinking का इस्तेमाल करके कंट्रोल किया जाता है. इस्तेमाल नहीं किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा, इस्तेमाल नहीं किए जाने वाले रिसॉर्स को हटाने की प्रोसेस को कोड ऑप्टिमाइज़ेशन पाइपलाइन के साथ इंटिग्रेट करने में मदद करती है. इससे ऐप्लिकेशन का साइज़ छोटा होता है और वे तेज़ी से काम करते हैं. कोड और संसाधन के रेफ़रंस, दोनों को एक साथ ऑप्टिमाइज़ करके, यह उन संसाधनों की पहचान करता है और उन्हें हटाता है जिन्हें सिर्फ़ इस्तेमाल न होने वाले कोड से रेफ़र किया गया है. यह ऑप्टिमाइज़ेशन की पिछली अलग-अलग प्रोसेस की तुलना में, एक अहम सुधार है.

यह खास तौर पर उन ऐप्लिकेशन के लिए मददगार है जो अलग-अलग फ़ॉर्म फ़ैक्टर वर्टिकल में काफ़ी संसाधन और कोड शेयर करते हैं. इससे ऐप्लिकेशन के साइज़ में 50% से ज़्यादा की कमी आई है. इससे ऐप्लिकेशन का साइज़ कम हो जाता है. इसलिए, इसे कम समय में डाउनलोड और इंस्टॉल किया जा सकता है. साथ ही, ऐप्लिकेशन के खुलने में कम समय लगता है, रेंडरिंग बेहतर होती है, और एएनआर की समस्याएं कम होती हैं. इससे उपयोगकर्ताओं को बेहतर अनुभव मिलता है.

लाइब्रेरी के नियम के हिसाब से फ़िल्टर करना: लाइब्रेरी के उपभोक्ता के नियमों में, ग्लोबल विकल्पों (उदाहरण के लिए, -dontobfuscate) के लिए सहायता बंद कर दी गई है. साथ ही, ऐप्लिकेशन उन्हें फ़िल्टर कर देंगे. ज़्यादा जानकारी के लिए, ग्लोबल विकल्प जोड़ना लेख पढ़ें.

Kotlin में शून्य वैल्यू की जांच: यह डिफ़ॉल्ट रूप से ऑप्टिमाइज़ की जाती है. इसे -processkotlinnullchecks का इस्तेमाल करके कंट्रोल किया जाता है. इस वर्शन में, बिल्ड की स्पीड में भी काफ़ी सुधार किए गए हैं. ज़्यादा जानकारी के लिए, अतिरिक्त ऑप्टिमाइज़ेशन के लिए ग्लोबल विकल्प लेख पढ़ें.

चुनिंदा पैकेज ऑप्टिमाइज़ करें: चुनिंदा पैकेज ऑप्टिमाइज़ करने के लिए, packageScope का इस्तेमाल किया जा सकता है. यह सुविधा एक्सपेरिमेंट के तौर पर उपलब्ध है. ज़्यादा जानकारी के लिए, packageScope की मदद से चुने गए पैकेज ऑप्टिमाइज़ करना लेख पढ़ें.

डिफ़ॉल्ट रूप से ऑप्टिमाइज़ किया गया: getDefaultProguardFile("proguard-android.txt") के लिए सहायता बंद कर दी गई है, क्योंकि इसमें -dontoptimize शामिल है. इसका इस्तेमाल नहीं किया जाना चाहिए. इसके बजाय, "proguard-android-optimize.txt" का इस्तेमाल करें. अगर आपको अपने ऐप्लिकेशन में ऑप्टिमाइज़ेशन की सुविधा को वैश्विक स्तर पर बंद करना है, तो proguard फ़ाइल में फ़्लैग को मैन्युअल तरीके से जोड़ें.
8.12 इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा: शुरुआती सहायता जोड़ी गई (android.r8.optimizedResourceShrinking का इस्तेमाल करके कंट्रोल की जाती है). इस्तेमाल न किए जाने वाले ऑप्टिमाइज़ रिसॉर्स को हटाने की सुविधा, इस्तेमाल न किए जाने वाले रिसॉर्स को हटाने की सुविधा को कोड ऑप्टिमाइज़ेशन पाइपलाइन के साथ इंटिग्रेट करने में मदद करती है. आपको इसे AGP के इस वर्शन में मैन्युअल तरीके से चालू करना होगा.

Logcat रीट्रेसिंग: Android Studio की Logcat विंडो में, अपने-आप रीट्रेसिंग होने की सुविधा उपलब्ध है.
8.6 बेहतर रीट्रैसिंग: इसमें सभी minSdk लेवल के लिए, डिफ़ॉल्ट रूप से फ़ाइल का नाम और लाइन नंबर रीट्रैसिंग शामिल है. इससे पहले, वर्शन 8.2 में minSdk 26+ की ज़रूरत होती थी.

R8 को अपडेट करने से यह पक्का करने में मदद मिलती है कि अस्पष्ट किए गए बिल्ड के स्टैक ट्रेस आसानी से और साफ़ तौर पर पढ़े जा सकते हैं. इस वर्शन में, लाइन नंबर और सोर्स फ़ाइलों को मैप करने के तरीके को बेहतर बनाया गया है. इससे Android Studio Logcat जैसे टूल के लिए, क्रैश को ओरिजनल सोर्स कोड में अपने-आप रीट्रैस करना आसान हो जाता है.
8.0 डिफ़ॉल्ट रूप से फ़ुल मोड: R8 का फ़ुल मोड, ज़्यादा बेहतर ऑप्टिमाइज़ेशन उपलब्ध कराता है. यह सुविधा डिफ़ॉल्ट रूप से चालू रहती है. android.enableR8.fullMode=false का इस्तेमाल करके, इससे ऑप्ट आउट किया जा सकता है.
7.0 फ़ुल मोड उपलब्ध है: इसे android.enableR8.fullMode=true का इस्तेमाल करके, ऑप्ट-इन करने की सुविधा के तौर पर लॉन्च किया गया था. फ़ुल मोड में, ज़्यादा बेहतर ऑप्टिमाइज़ेशन लागू किए जाते हैं. ऐसा इसलिए, क्योंकि यह मोड इस बारे में ज़्यादा सटीक अनुमान लगाता है कि आपका कोड, रिफ़्लेक्शन और अन्य डाइनैमिक सुविधाओं का इस्तेमाल कैसे करता है. इससे ऐप्लिकेशन का साइज़ कम हो जाता है और परफ़ॉर्मेंस बेहतर होती है. हालांकि, ज़रूरी कोड को हटाने से रोकने के लिए, इसमें अतिरिक्त कीप नियमों की ज़रूरत पड़ सकती है.

R8 का इस्तेमाल अन्य बिल्ड सिस्टम के साथ करना

AGP, Android ऐप्लिकेशन के लिए सुझाया गया और आधिकारिक तौर पर सपोर्ट किया जाने वाला बिल्ड सिस्टम है. हालांकि, Bazel जैसे किसी अन्य बिल्ड सिस्टम का इस्तेमाल भी किया जा सकता है. अगर Bazel का इस्तेमाल किया जा रहा है, तो R8 को अपनी बिल्ड पाइपलाइन में इंटिग्रेट किया जा सकता है. इससे अपने ऐप्लिकेशन को छोटा करने, उसे अस्पष्ट करने, और उसे ऑप्टिमाइज़ करने में मदद मिलती है.

Bazel का इस्तेमाल करके Android ऐप्लिकेशन को ऑप्टिमाइज़ करने के बारे में जानकारी के लिए, Bazel का rules_android दस्तावेज़ देखें. ध्यान दें कि Bazel को Android ऐप्लिकेशन डेवलपमेंट के लिए आधिकारिक तौर पर सपोर्ट नहीं किया जाता.