स्किप करने का बेहतर मोड

ज़्यादा स्किप करने की सुविधा, Compose कंपाइलर में उपलब्ध एक मोड है. चालू होने पर, यह दो तरीकों से कंपाइलर के व्यवहार को बदलता है:

वीडियो को तेज़ी से स्किप करने की सुविधा चालू करना

Kotlin 2.0.20 में, ज़्यादा तेज़ी से स्किप करने की सुविधा डिफ़ॉल्ट रूप से चालू होती है.

2.0.20 से पहले की रिलीज़ में, किसी Gradle मॉड्यूल के लिए 'पूरी तरह स्किप करें' सुविधा चालू करने के लिए, अपने Gradle कॉन्फ़िगरेशन के composeCompiler ब्लॉक में यह विकल्प शामिल करें:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

स्किप किया जा सकने वाला कॉम्पोज़ेबल

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

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

कब स्किप करें

Compose, फिर से कॉम्पोज़ करने के दौरान किसी कॉम्पोज़ेबल को स्किप करना है या नहीं, यह तय करने के लिए हर पैरामीटर की वैल्यू की तुलना उनकी पिछली वैल्यू से करता है. तुलना का टाइप, पैरामीटर की स्थिरता पर निर्भर करता है.

  • अस्थिर पैरामीटर की तुलना, इंस्टेंस की समानता (===) का इस्तेमाल करके की जाती है
  • स्थिर पैरामीटर की तुलना, ऑब्जेक्ट की समानता (Object.equals()) का इस्तेमाल करके की जाती है

अगर सभी पैरामीटर इन ज़रूरी शर्तों को पूरा करते हैं, तो Compose, फिर से कॉम्पोज़ करने के दौरान, कॉम्पोज़ किए गए कॉम्पोनेंट को स्किप कर देता है.

हो सकता है कि आप किसी कॉम्पोज़ेबल को, तेज़ी से स्किप करने की सुविधा से ऑप्ट आउट करना चाहें. इसका मतलब है कि आपको ऐसा कॉम्पोज़ेबल चाहिए जिसे फिर से शुरू किया जा सके, लेकिन स्किप न किया जा सके. इस मामले में, @NonSkippableComposable ऐनोटेशन का इस्तेमाल करें.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

क्लास को 'स्टैबल' के तौर पर एनोटेट करना

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

लैम्ब्डा मेमोइज़ेशन

स्किप करने का ज़्यादा बेहतर मोड चालू होने पर, कॉम्पोज़ेबल में मौजूद लैम्ब्डा फ़ंक्शन के लिए ज़्यादा मेमोइज़ेशन की सुविधा चालू होती है. 'पूरी तरह से स्किप करें' सुविधा चालू होने पर, कॉम्पोज़ेबल फ़ंक्शन में मौजूद हर लैम्ब्डा को अपने-आप याद रखा जाएगा.

उदाहरण

'पूरी तरह स्किप करें' सुविधा का इस्तेमाल करते समय, कॉम्पोज़ेबल में मौजूद लेम्ब्डा फ़ंक्शन को मेमोइज़ेशन करने के लिए, कंपाइलर आपके लेम्ब्डा फ़ंक्शन को remember कॉल के साथ रैप करता है. इसे लेम्ब्डा के कैप्चर के साथ डाला जाता है.

मान लें कि आपके पास इस उदाहरण में दिखाया गया कोई लैम्ब्डा फ़ंक्शन है:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

'ज़्यादा बार इस्तेमाल होने वाले फ़ंक्शन को स्किप करने की सुविधा' चालू होने पर, कंपाइलर लैम्ब्डा फ़ंक्शन को remember कॉल में रैप करके उसे मेमोइज़ करता है:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

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

मेमोइज़ेशन और फिर से कॉम्पोज़ करना

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

मेमोइज़ेशन से बचना

अगर आपके पास कोई ऐसा लैम्ब्डा फ़ंक्शन है जिसे आपको मेमोइज़ नहीं करना है, तो @DontMemoize के साथ एनोटेशन का इस्तेमाल करें.

val lambda = @DontMemoize {
    ...
}

APK का साइज़

कंपाइल करने पर, स्किप किए जा सकने वाले Composables के मुकाबले, स्किप नहीं किए जा सकने वाले Composables से ज़्यादा कोड जनरेट होता है. 'पूरी तरह स्किप करने की सुविधा' चालू होने पर, कंपाइलर सभी कॉम्पोज़ेबल को स्किप किए जा सकने वाले के तौर पर मार्क करता है. साथ ही, सभी लैम्ब्डा को remember{...} में रैप करता है. इस वजह से, गाने को तेज़ी से स्किप करने की सुविधा चालू करने से, आपके ऐप्लिकेशन के APK साइज़ पर बहुत कम असर पड़ता है.

Android पर अब उपलब्ध है में, वीडियो को तेज़ी से स्किप करने की सुविधा चालू करने पर, APK का साइज़ 4 केबी बढ़ गया. साइज़ में अंतर, ऐप्लिकेशन में पहले से मौजूद उन कॉम्पोज़ेबल की संख्या पर निर्भर करता है जिन्हें स्किप नहीं किया जा सकता. हालांकि, यह अंतर काफ़ी कम होना चाहिए.