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

शानदार

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 Asset Packaging Tool (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% से ज़्यादा की कमी देखी गई है. साइज़ कम होने से, डाउनलोड करने में कम समय लगता है, ऐप्लिकेशन तेज़ी से इंस्टॉल होते हैं, और उपयोगकर्ता अनुभव बेहतर होता है. साथ ही, ऐप्लिकेशन तेज़ी से शुरू होते हैं, रेंडरिंग बेहतर होती है, और एक से ज़्यादा बार, ऐप्लिकेशन से प्रतिक्रिया न मिलने (ANR) की समस्या कम होती है.

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