धीरे-धीरे ऑप्टिमाइज़ेशन को अपनाना

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

ऑप्टिमाइज़ेशन की सीमा तय करना

R8 कई तरह के ऑप्टिमाइज़ेशन करता है. जैसे, कोड हटाना, कोड फिर से लिखना, और संसाधन हटाना. यहां ऑप्टिमाइज़ेशन के अलग-अलग टाइप के बारे में खास जानकारी दी गई है:

  • कोड छोटा करना (या ट्री शेकिंग): बिना रेफ़रंस वाला कोड हटाता है
  • कोड को उलझाना (या आइडेंटिफ़ायर को छोटा करना): इससे क्लास और मेथड के नाम छोटे हो जाते हैं
  • ऑप्टिमाइज़ेशन: कोड को फिर से लिखता है, जैसे कि इनलाइन करना

गड़बड़ियों की संभावना को कम करने के लिए, इनमें से सिर्फ़ कुछ ऑप्टिमाइज़ेशन चालू करें.

सिर्फ़ ट्री शेकिंग की सुविधा चालू करना

कोड छोटा करने की सुविधा को ट्री शेकिंग भी कहा जाता है. यह उस कोड को हटा देती है जिसका रेफ़रंस नहीं दिया गया है. हमारा सुझाव है कि आप सिर्फ़ ट्री शेकिंग से शुरुआत करें, क्योंकि यह सबसे आसान तरीका है.

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

-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization

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

काम करने वाले डिवाइसों के लिए बने मोड का इस्तेमाल करना

डिफ़ॉल्ट रूप से, R8 फ़ुल मोड में चलता है. फ़ुल मोड में, साइज़ में काफ़ी कमी आती है और परफ़ॉर्मेंस बेहतर होती है. हालांकि, पहली बार साइज़ कम करने की सुविधा चालू करते समय, इसे कुछ समय के लिए बंद किया जा सकता है और कंपैट मोड का इस्तेमाल किया जा सकता है.

साथ काम करने वाले मोड का इस्तेमाल करने के लिए, अपनी gradle.properties फ़ाइल में इस सेटिंग का इस्तेमाल करें:

android.enableR8.fullMode = false // Use temporarily to disable full mode

बाकी ऑप्टिमाइज़ेशन चालू करना

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

स्टैक ट्रेस को डिकोड करने के बारे में ज़्यादा जानने के लिए, मूल स्टैक ट्रेस को वापस पाना लेख पढ़ें.

ऑप्टिमाइज़ेशन के दायरे को सीमित करना

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

पैकेज के लिए, डेटा को सेव रखने के नियमों का इस्तेमाल करना

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

उदाहरण के लिए, अगर आपके ऐप्लिकेशन का कोई हिस्सा Gson का ज़्यादा इस्तेमाल करता है और इससे ऑप्टिमाइज़ेशन में समस्याएं आ रही हैं, तो इसे ठीक करने के लिए ज़्यादा टारगेट किए गए 'रखें' नियम जोड़ें या codegen समाधान का इस्तेमाल करें. हालांकि, बाकी ऐप्लिकेशन को ऑप्टिमाइज़ करने से जुड़ी समस्या को हल करने के लिए, Gson टाइप को तय करने वाले कोड को किसी खास सब-पैकेज में रखा जा सकता है. साथ ही, अपनी proguard-rules.pro फ़ाइल में इस तरह का नियम जोड़ा जा सकता है:

-keep class com.myapp.json.** { *; }

अगर इस्तेमाल की जा रही किसी लाइब्रेरी में इंटरनल कॉम्पोनेंट में रिफ़्लेक्शन है, तो पूरी लाइब्रेरी के लिए भी इसी तरह से 'रखें' नियम जोड़ा जा सकता है. आपको लाइब्रेरी के कोड या JAR/AAR की जांच करनी होगी, ताकि आपके पास सही पैकेज हो. हम ऐसा करने का सुझाव नहीं देते कि इसे लंबे समय तक इस्तेमाल किया जाए. हालांकि, इससे ऐप्लिकेशन के बाकी हिस्सों को ऑप्टिमाइज़ करने में मदद मिल सकती है:

-keep class com.somelibrary.** { *; }

पैकेज के लिए, डेटा को सेव रखने के नियम हटाना

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

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