प्रॉडक्ट से जुड़ी खबरें

R8 के लिए, कोड छोटा करने के नियमों को कॉन्फ़िगर करना और उनसे जुड़ी समस्याओं को हल करना

सात मिनट में पढ़ें
Ajesh Pai & Ben Weiss

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

R8 को चालू करना, ऐप्लिकेशन को रिलीज़ के लिए तैयार करने का एक अहम चरण है. हालांकि, इसके लिए डेवलपर को "सुरक्षित रखने के नियम" के तौर पर दिशा-निर्देश देने होते हैं.

इस लेख को पढ़ने के बाद, YouTube पर R8 ऑप्टिमाइज़र को चालू करने, डीबग करने, और समस्या हल करने के बारे में जानकारी देने वाला परफ़ॉर्मेंस स्पॉटलाइट वीक वीडियो देखें.

 

 

डेटा को सुरक्षित रखने के नियमों की ज़रूरत क्यों होती है

Keep के नियमों को लिखने की ज़रूरत इसलिए पड़ती है, क्योंकि R8 एक स्टैटिक एनालिसिस टूल है. हालांकि, Android ऐप्लिकेशन अक्सर डाइनैमिक एक्ज़ीक्यूशन पैटर्न पर निर्भर करते हैं. जैसे, JNI (Java Native Interface) का इस्तेमाल करके नेटिव कोड में रिफ़्लेक्शन या कॉल.

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

सुरक्षित रखने का नियम, R8 कंपाइलर को दिया गया एक निर्देश होता है. इसमें यह बताया जाता है कि "यह क्लास, तरीका या फ़ील्ड एक एंट्री पॉइंट है, जिसे रनटाइम के दौरान डाइनैमिक तरीके से ऐक्सेस किया जाएगा. आपको इसे रखना होगा. भले ही, आपको इसका कोई सीधा रेफ़रंस न मिले."

Keep Rules के बारे में ज़्यादा जानने के लिए, आधिकारिक गाइड देखें.

Keep के नियम कहां लिखें

किसी ऐप्लिकेशन के लिए, Keep के कस्टम नियम टेक्स्ट फ़ाइल में लिखे जाते हैं. आम तौर पर, इस फ़ाइल का नाम proguard-rules.pro होता है. यह ऐप्लिकेशन या लाइब्रेरी मॉड्यूल के रूट में मौजूद होती है. इसके बाद, इस फ़ाइल को आपके मॉड्यूल की build.gradle.kts फ़ाइल के release बिल्ड टाइप में तय किया जाता है.

release {

    isShrinkResources = true

    isMinifyEnabled = true

    proguardFiles(

        getDefaultProguardFile("proguard-android-optimize.txt"),

        "proguard-rules.pro",

    )

}

सही डिफ़ॉल्ट फ़ाइल का इस्तेमाल करना

getDefaultProguardFile तरीके से, Android SDK की ओर से दिए गए नियमों का डिफ़ॉल्ट सेट इंपोर्ट किया जाता है. गलत फ़ाइल का इस्तेमाल करने पर, हो सकता है कि आपका ऐप्लिकेशन ऑप्टिमाइज़ न हो. proguard-android-optimize.txt का इस्तेमाल करना न भूलें. इस फ़ाइल में, स्टैंडर्ड Android कॉम्पोनेंट के लिए डिफ़ॉल्ट कीप नियम दिए गए हैं. साथ ही, यह R8 को कोड ऑप्टिमाइज़ेशन की सुविधा चालू करने की अनुमति देता है. पुराना proguard-android.txt सिर्फ़ कीप नियम उपलब्ध कराता है. हालांकि, यह R8 के ऑप्टिमाइज़ेशन को चालू नहीं करता.

progaurd.png

यह परफ़ॉर्मेंस से जुड़ी एक गंभीर समस्या है. इसलिए, हम डेवलपर को गलत फ़ाइल का इस्तेमाल करने के बारे में चेतावनी दे रहे हैं. यह चेतावनी, Android Studio Narwhal 3 Feature Drop से शुरू होगी. साथ ही, Android Gradle प्लग इन 9.0 वर्शन से, हम पुरानी proguard-android.txt फ़ाइल के साथ काम नहीं करेंगे. इसलिए, पक्का करें कि आपने ऑप्टिमाइज़ किए गए वर्शन पर अपग्रेड कर लिया हो.

Keep के नियम लिखने का तरीका

डेटा सुरक्षित रखने के नियम के तीन मुख्य हिस्से होते हैं:

  1. कोई विकल्प जैसे कि -keep या -keepclassmembers
  2. ज़रूरी नहीं है कि मॉडिफ़ायर जैसे कि allowshrinking
  3. क्लास स्पेसिफ़िकेशन, जो मैच करने के लिए कोड तय करता है

पूरे सिंटैक्स और उदाहरणों के लिए, डेटा सुरक्षित रखने के नियम जोड़ने से जुड़े दिशा-निर्देश देखें.

Keep Rule के एंटी-पैटर्न

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

ग्लोबल ऑप्शन

ये फ़्लैग, ग्लोबल टॉगल होते हैं. इनका इस्तेमाल रिलीज़ बिल्ड में कभी नहीं किया जाना चाहिए. इनका इस्तेमाल सिर्फ़ कुछ समय के लिए डीबग करने के लिए किया जाता है, ताकि किसी समस्या का पता लगाया जा सके.

-dontotptimize का इस्तेमाल करने से, R8 के परफ़ॉर्मेंस ऑप्टिमाइज़ेशन की सुविधा बंद हो जाती है. इससे ऐप्लिकेशन धीरे काम करता है.

-dontobfuscate का इस्तेमाल करने पर, नाम बदलने की सुविधा बंद हो जाती है. वहीं, -dontshrink का इस्तेमाल करने पर, ऐसे कोड को हटाने की सुविधा बंद हो जाती है जिसका इस्तेमाल नहीं किया जाता. इन दोनों ग्लोबल नियमों से, ऐप्लिकेशन का साइज़ बढ़ जाता है.

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

निजी डेटा के रखरखाव के बहुत ज़्यादा सामान्य नियम

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

-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMS

इनवर्ज़न ऑपरेटर (!)

इनवर्ज़न ऑपरेटर (!) का इस्तेमाल करके, किसी पैकेज को नियम से बाहर रखा जा सकता है. हालांकि, यह इतना आसान नहीं है. इस उदाहरण को देखें:

-keep class !com.example.my_package.** { *; } // USE WITH CAUTION

आपको लग सकता है कि इस नियम का मतलब है कि "क्लास को com.example.package में न रखें." हालांकि, इसका मतलब है कि "ऐप्लिकेशन में मौजूद हर क्लास, तरीके, और प्रॉपर्टी को  com.example.package में न रखें." अगर आपको यह जानकर हैरानी हुई है, तो R8 कॉन्फ़िगरेशन में किसी भी तरह के नेगेशन की जांच करें.

Android कॉम्पोनेंट के लिए ज़रूरत से ज़्यादा नियम

एक और आम गलती यह है कि अपने ऐप्लिकेशन के ActivitiesServices या BroadcastReceivers के लिए, Keep Rules को मैन्युअल तरीके से जोड़ा जाता है. यह ज़रूरी नहीं है. डिफ़ॉल्ट proguard-android-optimize.txt फ़ाइल में, इन स्टैंडर्ड Android कॉम्पोनेंट के लिए ज़रूरी नियम पहले से शामिल होते हैं, ताकि ये तुरंत काम करना शुरू कर दें.

साथ ही, कई लाइब्रेरी अपने खुद के Keep Rules भी लाती हैं. इसलिए, आपको इनके लिए अपने नियम नहीं लिखने चाहिए. अगर आपको इस्तेमाल की जा रही किसी लाइब्रेरी के Keep Rules से जुड़ी कोई समस्या आ रही है, तो सबसे अच्छा तरीका है कि आप लाइब्रेरी के लेखक से संपर्क करें. इससे आपको समस्या के बारे में पता चल पाएगा.

Keep Rule के सबसे सही तरीके

अब आपको पता चल गया है कि क्या नहीं करना चाहिए. इसलिए, आइए अब सबसे सही तरीकों के बारे में बात करते हैं.

Keep के लिए सटीक नियम लिखना

Keep के अच्छे नियमों को ज़्यादा से ज़्यादा सटीक और खास होना चाहिए. उन्हें सिर्फ़ ज़रूरी कॉम्पोनेंट को सुरक्षित रखना चाहिए, ताकि R8 बाकी सभी कॉम्पोनेंट को ऑप्टिमाइज़ कर सके.
 

नियमक्वालिटी

 

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

 

कम: पूरे पैकेज और उसके सबपैकेज को बनाए रखता है

 

-keep class com.example.MyClass { ; }

 

कम: यह पूरी क्लास को सुरक्षित रखता है. हालांकि, यह अब भी बहुत ज़्यादा है
-keepclassmembers class com.example.MyClass {

    private java.lang.String secretMessage;

    public void onNativeEvent(java.lang.String);

}
ज़्यादा: किसी क्लास से सिर्फ़ काम के तरीके और प्रॉपर्टी रखी जाती हैं

कॉमन ऐनसेस्टर का इस्तेमाल करना

अलग-अलग डेटा मॉडल के लिए अलग-अलग Keep Rule लिखने के बजाय, एक ऐसा नियम लिखें जो किसी सामान्य बेस क्लास या इंटरफ़ेस को टारगेट करता हो. यहां दिया गया नियम, R8 को यह निर्देश देता है कि वह इस इंटरफ़ेस को लागू करने वाली क्लास के सभी सदस्यों को सुरक्षित रखे. साथ ही, इसे आसानी से बढ़ाया जा सकता है.

# Keep all fields of any class that implements SerializableModel

-keepclassmembers class * implements com.example.models.SerializableModel {

    <fields>;

}

एक से ज़्यादा क्लास को टारगेट करने के लिए, एनोटेशन का इस्तेमाल करना

कस्टम एनोटेशन (जैसे, @Serialize) बनाएं और इसका इस्तेमाल उन क्लास को "टैग" करने के लिए करें जिनके फ़ील्ड को सुरक्षित रखना है. यह एक और साफ़, डिक्लेरेटिव, और आसानी से बढ़ाया जा सकने वाला पैटर्न है. आपने जिन फ़्रेमवर्क का इस्तेमाल किया है उनसे पहले से मौजूद एनोटेशन के लिए, Keep के नियम बनाए जा सकते हैं.

# Keep all fields of any class annotated with @Serialize

-keepclassmembers class * {

    @com.example.annotations.Serialize <fields>;

}

सही कीप ऑप्शन चुनना

कीप ऑप्शन, नियम का सबसे अहम हिस्सा होता है. गलत विकल्प चुनने से, ऑप्टिमाइज़ेशन की सुविधा बंद हो सकती है.

Keep Optionयह सुविधा क्या करती है
-keepइससे क्लास और डिक्लेरेशन में शामिल कोड कॉम्पोनेंट को हटाने या उनके नाम बदलने पर रोक लग जाती है.
-keepclassmembersइससे तय किए गए सदस्यों को हटाने या उनका नाम बदलने से रोका जाता है. हालांकि, इससे क्लास को हटाने की अनुमति मिलती है. ऐसा सिर्फ़ उन क्लास के लिए किया जा सकता है जिन्हें किसी और तरीके से नहीं हटाया गया है.
-keepclasseswithmembersयह विकल्प, क्लास और उसके कोड कॉम्पोनेंट को सुरक्षित रखता है. हालांकि, ऐसा सिर्फ़ तब किया जाता है, जब क्लास में उसके सभी कोड कॉम्पोनेंट मौजूद हों.

Keep Options के दस्तावेज़ में, Keep ऑप्शन के बारे में ज़्यादा जानकारी दी गई है.

मॉडिफ़ायर की मदद से ऑप्टिमाइज़ करने की अनुमति दें

allowshrinking और allowobfuscation जैसे मॉडिफ़ायर, -keep के नियम को आसान बनाते हैं. इससे R8 को ऑप्टिमाइज़ेशन की सुविधा वापस मिल जाती है. उदाहरण के लिए, अगर कोई लेगसी लाइब्रेरी आपको पूरी क्लास पर -keep का इस्तेमाल करने के लिए मजबूर करती है, तो सिकुड़ने और अस्पष्ट करने की अनुमति देकर, कुछ ऑप्टिमाइज़ेशन वापस पाया जा सकता है:

# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it.

-keep,allowshrinking,allowobfuscation class com.example.LegacyClass

अतिरिक्त ऑप्टिमाइज़ेशन के लिए ग्लोबल विकल्प जोड़ना

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

-repackageclasses एक ऐसा विकल्प है जो R8 को सभी अस्पष्ट क्लास को एक ही पैकेज में ले जाने का निर्देश देता है. इससे, पैकेज के नाम वाली गैर-ज़रूरी स्ट्रिंग को हटाने पर, DEX फ़ाइल में काफ़ी जगह बचती है.

-allowaccessmodification की मदद से, R8 को ज़्यादा ऐक्सेस (जैसे, private से public) मिलता है, ताकि वह ज़्यादा बेहतर तरीके से इनलाइनिंग कर सके. proguard-android-optimize.txt का इस्तेमाल करते समय, यह सुविधा अब डिफ़ॉल्ट रूप से चालू होती है.

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

इसे और भी ज़्यादा साफ़ तौर पर समझने के लिए, हम Android Gradle प्लग इन के 9.0 वर्शन में, लाइब्रेरी से मिलने वाले ग्लोबल ऑप्टिमाइज़ेशन फ़्लैग को पूरी तरह से अनदेखा करना शुरू कर देंगे. 

लाइब्रेरी के लिए सबसे सही तरीके

हर Android ऐप्लिकेशन, किसी न किसी तरह से लाइब्रेरी पर निर्भर होता है. इसलिए, आइए लाइब्रेरी के सबसे सही तरीकों के बारे में बात करते हैं.

लाइब्रेरी डेवलपर के लिए

अगर आपकी लाइब्रेरी में रिफ़्लेक्शन या JNI का इस्तेमाल किया जाता है, तो आपको उपभोक्ताओं के लिए ज़रूरी कीप नियम देने होंगे. इन नियमों को consumer-rules.pro फ़ाइल में रखा जाता है. इसके बाद, इसे लाइब्रेरी की एएआर फ़ाइल में अपने-आप बंडल कर दिया जाता है.

android {

    defaultConfig {

        consumerProguardFiles("consumer-rules.pro")

    }

    ...

}

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

Keep के उन नियमों को फ़िल्टर करना जिनमें समस्याएं हैं

अगर आपको ऐसी लाइब्रेरी का इस्तेमाल करना है जिसमें Keep Rules से जुड़ी समस्याएं हैं, तो AGP 9.0 या इसके बाद के वर्शन में, build.gradle.kts फ़ाइल में जाकर उन्हें फ़िल्टर किया जा सकता है. इससे R8 को यह पता चलता है कि किसी खास डिपेंडेंसी से आने वाले नियमों को अनदेखा करना है.

release {

    optimization.keepRules {

        // Ignore all consumer rules from this specific library

        it.ignoreFrom("com.somelibrary:somelibrary")

    }

}

सबसे अच्छा कीप रूल, कोई कीप रूल न होना है

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

लाइब्रेरी चुनने के तरीके के बारे में ज़्यादा जानने के लिए, लाइब्रेरी सोच-समझकर चुनें लेख पढ़ें.

R8 कॉन्फ़िगरेशन को डीबग करना और उससे जुड़ी समस्याओं को हल करना

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

डुप्लीकेट और ग्लोबल Keep के नियम ढूंढना

R8, कई सोर्स से नियमों को मर्ज करता है. इसलिए, यह जानना मुश्किल हो सकता है कि "फ़ाइनल" नियमों का सेट क्या है. इस फ़्लैग को अपनी proguard-rules.pro फ़ाइल में जोड़ने से, पूरी रिपोर्ट जनरेट होती है:

# Outputs the final, merged set of rules to the specified file

-printconfiguration build/outputs/logs/configuration.txt

इस फ़ाइल में, एक जैसे नियमों को खोजने या किसी समस्या वाले नियम (जैसे, -dontoptimize) का पता लगाने के लिए, इसे खोजा जा सकता है. इससे यह पता लगाया जा सकता है कि इस नियम को किस लाइब्रेरी में शामिल किया गया था.

R8 से पूछें: इसे क्यों सेव किया जा रहा है?

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

# Asks R8 to explain why it's keeping a specific class

class com.example.MyUnusedClass

-whyareyoukeeping 

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

पूरी गाइड के लिए, R8 से जुड़ी समस्या हल करना सेक्शन देखें.

अगले चरण

R8, Android ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाने के लिए एक बेहतरीन टूल है. यह स्टैटिक विश्लेषण इंजन के तौर पर कैसे काम करता है, इसकी सही जानकारी होने पर ही इसका असर दिखता है.

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

परफ़ॉर्मेंस स्पॉटलाइट हफ़्ते के दौरान, आज का स्पॉटलाइट हफ़्ते का वीडियो YouTube पर ज़रूर देखें. साथ ही, R8 चैलेंज में हिस्सा लेना जारी रखें. R8 को चालू करने या उससे जुड़ी किसी समस्या को हल करने के बारे में कोई सवाल पूछने के लिए, #optimizationEnabled का इस्तेमाल करें. हम यहां आपकी मदद करने के लिए हैं.

अब समय आ गया है कि आप खुद इन फ़ायदों को देखें.

हमारा सुझाव है कि आप अपने ऐप्लिकेशन के लिए, R8 का फ़ुल मोड आज ही चालू करें.

  1. शुरू करने के लिए, हमारी डेवलपर गाइड देखें: ऐप्लिकेशन ऑप्टिमाइज़ेशन चालू करना.
  2. देखें कि क्या अब भी proguard-android.txt का इस्तेमाल किया जा रहा है. अगर हां, तो इसे proguard-android-optimize.txt से बदलें.
  3. इसके बाद, असर का आकलन करें. सिर्फ़ अंतर को महसूस न करें, बल्कि इसकी पुष्टि करें. स्टार्टअप से पहले और बाद में, स्टार्टअप में लगने वाले समय को मेज़र करने के लिए,  GitHub पर मौजूद हमारे Macrobenchmark के सैंपल ऐप्लिकेशन से कोड को अडॉप्ट करके, अपनी परफ़ॉर्मेंस में हुए सुधार को मेज़र करें.

हमें भरोसा है कि इससे आपके ऐप्लिकेशन की परफ़ॉर्मेंस में काफ़ी सुधार होगा.

इसके अलावा, अपने सवाल पूछने के लिए सोशल टैग #AskAndroid का इस्तेमाल करें. हमारे विशेषज्ञ पूरे हफ़्ते आपके सवालों की निगरानी करते हैं और उनके जवाब देते हैं.

कल के सेशन में, हम बेसलाइन और स्टार्टअप प्रोफ़ाइलों के साथ-साथ, प्रोफ़ाइल गाइडेड ऑप्टिमाइज़ेशन के बारे में बात करेंगे. हम यह भी शेयर करेंगे कि पिछली रिलीज़ में कंपोज़ रेंडरिंग की परफ़ॉर्मेंस कैसे बेहतर हुई. साथ ही, बैकग्राउंड में होने वाले काम के लिए परफ़ॉर्मेंस से जुड़ी बातों को शेयर करेंगे.

इसे लिखा है:

पढ़ना जारी रखें