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

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

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

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.
            }
        }
    }
}

शानदार

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 कॉन्फ़िगरेशन ऐनलिसिस का इस्तेमाल करें.

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

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

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

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

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

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

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

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

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

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

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

bash android.enableR8.fullMode=false # Remove this line from your codebase.

ध्यान दें कि ऐप्लिकेशन ऑप्टिमाइज़ेशन की सुविधा चालू करने पर, स्टैक ट्रेस को समझना मुश्किल हो जाता है. ऐसा खास तौर पर तब होता है, जब 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 का इस्तेमाल करके, ऑप्ट-इन करने की सुविधा के तौर पर लॉन्च किया गया था. फ़ुल मोड में, ज़्यादा बेहतर ऑप्टिमाइज़ेशन लागू किए जाते हैं. ऐसा इसलिए, क्योंकि यह मोड इस बारे में ज़्यादा सटीक अनुमान लगाता है कि आपका कोड, रिफ़्लेक्शन और अन्य डाइनैमिक सुविधाओं का इस्तेमाल कैसे करता है. इससे ऐप्लिकेशन का साइज़ कम हो जाता है और परफ़ॉर्मेंस बेहतर होती है. हालांकि, ज़रूरी कोड को हटाने से रोकने के लिए, इसमें अतिरिक्त कीप नियमों की ज़रूरत पड़ सकती है.