Composition: सार, Compose में UI ट्री का निर्माण

लेखक: IT Sectr प्रकाशित: 2026-06-27 पढ़ने का समय: 7 मिनट

Composition Jetpack Compose में केंद्रीय प्रक्रिया है, जिसके दौरान वर्णनात्मक Composable फ़ंक्शन से स्क्रीन पर प्रदर्शित एक जीवित UI ट्री बनाया जाता है। Android View सिस्टम के विपरीत, जहाँ लेआउट XML से लोड किए जाते थे और अपरिवर्तनीय ऑब्जेक्ट में बदल दिए जाते थे, Composition एक गतिशील सिस्टम के रूप में काम करता है: फ़ंक्शन निष्पादित होते हैं, मेमोरी में स्लॉट बनाते हैं, नोड पदानुक्रम बनाते हैं और इसे स्थिति से बाँधते हैं। Google Android Developers, 2026 के अनुसार, Compose अनुप्रयोगों के प्रदर्शन को अनुकूलित करने के लिए Composition को समझना महत्वपूर्ण है।

मुख्य बिंदु

  • Composition UI ट्री बनाने के लिए Composable फ़ंक्शन का निष्पादन है
  • स्लॉट मेमोरी कोशिकाएँ हैं जो प्रत्येक फ़ंक्शन के पैरामीटर और स्थिति संग्रहीत करती हैं
  • स्थिति Compose में (Positional Memorization) स्थिति को कोड में स्थान से बाँधती है
  • पहला पास Composition स्क्रीन शुरू होने पर प्रारंभिक UI ट्री बनाता है
  • CompositionLocal स्पष्ट पैरामीटर के बिना ट्री के माध्यम से डेटा पास करता है

Jetpack Compose में Composition क्या है

Composition Composable फ़ंक्शन को निष्पादित करने की प्रक्रिया है, जिसके परिणामस्वरूप उपयोगकर्ता इंटरफ़ेस का नोड्स के ट्री के रूप में आंतरिक प्रतिनिधित्व बनता है। इस ट्री का प्रत्येक नोड या तो अंतर्निहित घटक (Text, Button, Image) से या उपयोगकर्ता-परिभाषित Composable फ़ंक्शन के कॉल से मेल खाता है। Composition सीधे Android View ऑब्जेक्ट नहीं बनाता — यह एक अमूर्त विवरण बनाता है जिसे बाद में Layout और Drawing चरणों द्वारा संसाधित किया जाता है।

Composition की मुख्य विशेषता इसकी पुनरारंभ क्षमता है। संरचना में प्रत्येक Composable फ़ंक्शन को किसी भी समय पुनरारंभ किया जा सकता है यदि इसके इनपुट पैरामीटर या इसके द्वारा पढ़ी गई स्थिति ऑब्जेक्ट बदल गए हैं। सिस्टम पूरे ट्री को पुनरारंभ नहीं करता — केवल उन फ़ंक्शन को जो वास्तव में बदले गए डेटा पर निर्भर करते हैं।

तकनीकी रूप से, Composition Composer के माध्यम से प्रबंधित किया जाता है — एक आंतरिक इंजन जो Kotlin कंपाइलर प्रत्येक Composable फ़ंक्शन में एम्बेड करता है। Composer स्लॉट (स्थिति समूह) में जानकारी लिखता है कि कौन से फ़ंक्शन कॉल किए गए, किन पैरामीटर के साथ और किस क्रम में। बाद के कॉल पर, Composer नए डेटा की तुलना संग्रहीत डेटा से करता है और पुनरारंभ करने का निर्णय लेता है।

Composition के दौरान UI ट्री कैसे बनता है

UI ट्री बनाने की प्रक्रिया Activity या Fragment के अंदर setContent विधि को कॉल करने से शुरू होती है। यह विधि प्रारंभिक Composition बनाती है और रूट Composable फ़ंक्शन को निष्पादित करना शुरू करती है। फिर प्रत्येक नेस्टेड Composable फ़ंक्शन अपने नोड्स को ट्री में जोड़ता है, एक पदानुक्रम बनाता है: Row में Text और Button होते हैं, Column में Image और Card होते हैं, और इसी तरह।

प्रत्येक ट्री नोड को स्रोत कोड में इसकी स्थिति के आधार पर एक अद्वितीय स्थिति कुंजी प्राप्त होती है। इस कुंजी का उपयोग बाद के निष्पादन के दौरान नोड की पहचान करने के लिए किया जाता है। स्थिति कुंजी वह कारण है जिसके कारण Composable फ़ंक्शन को कॉल करने का क्रम शर्तों पर निर्भर नहीं होना चाहिए: यदि एक रन में A -> B कॉल किया जाता है, और अगले में B -> A, तो Compose पुराने और नए नोड्स का मिलान नहीं कर पाएगा।

kotlin
@Composable
fun AppScreen() {
    Column {                     // Column नोड (स्थिति 1)
        HeaderSection()            // HeaderSection नोड (स्थिति 2)
        ContentSection()           // ContentSection नोड (स्थिति 3)
        FooterSection()            // FooterSection नोड (स्थिति 4)
    }
}

@Composable
fun HeaderSection() {
    Row {                       // Row नोड (स्थिति 2.1)
        Text("शीर्षक")         // Text नोड (स्थिति 2.2)
        Icon(...)                // Icon नोड (स्थिति 2.3)
    }
}

इस उदाहरण में, प्रत्येक कॉल को कोड में क्रम के आधार पर एक स्थिति प्राप्त होती है। Column (स्थिति 1) में तीन चाइल्ड नोड (स्थितियाँ 2, 3, 4) हैं। HeaderSection दो और चाइल्ड नोड (2.1, 2.2, 2.3) जोड़ता है। यदि अगली पुनर्संरचना में ContentSection को HeaderSection से पहले कॉल किया जाता है, तो Composer नोड्स का सही ढंग से मिलान नहीं कर पाएगा — इसलिए नियम: Composable फ़ंक्शन कॉल का क्रम स्थिर होना चाहिए।

Composition में स्थिति प्रबंधन

Composition में स्थिति State<T> प्रकार की ऑब्जेक्ट के माध्यम से प्रबंधित की जाती है। जब कोई Composable फ़ंक्शन प्रत्यायोजित गुण (by) के माध्यम से State से मान पढ़ता है, तो वह उस State पर निर्भरता पंजीकृत करता है। जब मान बदलता है, तो इस State को पढ़ने वाले सभी फ़ंक्शन अगले संरचना चरण में पुनरारंभ के लिए चिह्नित किए जाते हैं।

निर्भरता पंजीकरण तंत्र को snapshot सिस्टम कहा जाता है। हर बार जब State बदलता है, एक snapshot सभी परिवर्तनों को रिकॉर्ड करता है और Composer को सूचित करता है कि कौन से फ़ंक्शन उस State पर निर्भर करते हैं। यह समझना महत्वपूर्ण है: गैर-Composable कोड (जैसे, onClick लैम्ब्डा में) में State पढ़ना निर्भरता पंजीकृत नहीं करता — केवल Composable फ़ंक्शन के अंदर या संरचना संदर्भ में निष्पादित लैम्ब्डा में पढ़ना।

Snapshot सिस्टम लेन-देन संबंधी काम करता है: एक ही घटना के भीतर कई State परिवर्तन एक लेन-देन में संयुक्त होते हैं, जो कई पुनर्संरचनाओं को रोकता है। यह विशेष रूप से जेस्चर को संभालते समय महत्वपूर्ण है: एक गति कई State ऑब्जेक्ट बदलती है, लेकिन Compose केवल एक पुनर्संरचना करता है।

kotlin
@Composable
fun StateExample() {
    var text by remember { mutableStateOf("Hello") }
    var isVisible by remember { mutableStateOf(true) }

    Column {
        Text(text)  // टेक्स्ट पर निर्भरता पंजीकृत करता है

        if (isVisible) {  // isVisible पर निर्भरता पंजीकृत करता है
            TextField(value = text, onValueChange = { text = it })
        }

        Button(onClick = { isVisible = !isVisible }) {
            Text(if (isVisible) "छिपाएँ" else "दिखाएँ")
        }
    }
}

टेक्स्ट बदलने से केवल Column, Text और TextField की पुनर्संरचना होती है। Column, Button और isVisible शर्त अपरिवर्तित रहती है। पुनर्संरचना का यह अलगाव Compose का उन सिस्टमों पर एक मुख्य लाभ है जो पूरी स्क्रीन को फिर से चित्रित करते हैं। प्रत्येक Composable फ़ंक्शन केवल उन State ऑब्जेक्ट को ट्रैक करता है जिन्हें वह सीधे पढ़ता है।

Composition बनाम Recomposition: मुख्य अंतर

Composition और Recomposition Composable फ़ंक्शन को निष्पादित करने के दो अलग-अलग तरीके हैं। Composition स्क्रीन बनने पर एक बार होता है: सिस्टम सभी Composable फ़ंक्शन को प्रारंभिक मानों के साथ निष्पादित करता है और प्रारंभिक UI ट्री बनाता है। Recomposition डेटा बदलने पर कई बार होता है: सिस्टम केवल उन फ़ंक्शन को पुनरारंभ करता है जो बदली हुई स्थिति पर निर्भर करते हैं।

मोड Composition सभी ट्री नोड को सक्रिय करता है, प्रत्येक फ़ंक्शन के लिए स्लॉट आवंटित करता है, और सभी वंशजों को पंजीकृत करता है। Recomposition चयनात्मक रूप से काम करता है: Compose प्रत्येक फ़ंक्शन के नए और पुराने पैरामीटर मानों की तुलना करता है, और यदि वे नहीं बदले हैं — तो फ़ंक्शन निष्पादित नहीं होता (skipping)।

Composition और Recomposition लागत में भिन्न हैं। पहला Composition अधिक महंगा है क्योंकि इसमें पूर्ण ट्री निर्माण और स्लॉट आवंटन की आवश्यकता होती है। Recomposition सस्ता है, खासकर यदि अधिकांश फ़ंक्शन स्थिर हैं — उनके पैरामीटर equals द्वारा तुलना किए जाते हैं, और Compose उनके आह्वान को छोड़ देता है। अधिकतम प्रदर्शन के लिए, आपको प्रयास करना चाहिए कि अधिकांश पुनर्संरचनाएँ यथासंभव कम फ़ंक्शन को प्रभावित करें।

विशेषताCompositionRecomposition
कब होता हैएक बार, पहले प्रदर्शन परकई बार, डेटा बदलने पर
दायरापूरा ट्रीकेवल बदले हुए फ़ंक्शन
पैरामीटर तुलनानहीं की जातीछोड़ने के लिए की जाती है
स्लॉट निर्माणहाँ, सभी स्लॉट बनाए जाते हैंकेवल नए नोड के लिए

CompositionLocal: ट्री के माध्यम से डेटा पास करना

CompositionLocal संरचना ट्री के माध्यम से अंतर्निहित रूप से डेटा पास करने का एक तंत्र है। यह समस्या को हल करता है जब किसी पैरामीटर को दर्जनों नेस्टेड Composable फ़ंक्शन के माध्यम से पास करने की आवश्यकता होती है जो इसे सीधे उपयोग नहीं करते हैं। स्पष्ट पैरामीटर श्रृंखला के बजाय, डेटा शीर्ष स्तर पर सेट किया जाता है और CompositionLocal.current के माध्यम से किसी भी नेस्टेड फ़ंक्शन में पढ़ा जाता है।

MaterialTheme CompositionLocal का सबसे प्रसिद्ध उदाहरण है। सभी Compose घटक MaterialTheme.colorScheme, MaterialTheme.typography, MaterialTheme.shapes के माध्यम से रंग, टाइपोग्राफी और आकार पढ़ते हैं, बिना उन्हें पैरामीटर के माध्यम से प्राप्त किए। डेवलपर वर्तमान उपयोगकर्ता, स्थानीयकरण सेटिंग्स या स्क्रीन कॉन्फ़िगरेशन जैसे डेटा के लिए अपना स्वयं का CompositionLocal बना सकते हैं।

एक महत्वपूर्ण सीमा: CompositionLocal का उपयोग बार-बार बदलने वाले डेटा (स्क्रॉल स्थिति, इनपुट फ़ील्ड में टेक्स्ट) के लिए नहीं किया जाना चाहिए। CompositionLocal पढ़ने वाला घटक हर बार मान बदलने पर पुनरारंभ होता है, इसलिए गतिशील डेटा के लिए स्पष्ट पैरामीटर या State का उपयोग करना बेहतर है। CompositionLocal कॉन्फ़िगरेशन डेटा के लिए इष्टतम है जो शायद ही कभी या कभी नहीं बदलता है।

kotlin
val LocalUser = compositionLocalOf<User?> { null }

@Composable
fun AppRoot(user: User, content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalUser.provides(user)) {
        content()
    }
}

@Composable
fun UserAvatar() {
    val user = LocalUser.current  // स्पष्ट पैरामीटर के बिना पढ़ना
    AsyncImage(model = user?.avatarUrl, contentDescription = "Avatar")
}

CompositionLocalProvider एक दायरा बनाता है जिसके भीतर LocalUser.current निर्दिष्ट मान लौटाता है। UserAvatar मध्यवर्ती फ़ंक्शन के माध्यम से पैरामीटर स्पष्ट रूप से पास किए बिना उपयोगकर्ता को पढ़ता है। यह गहरे पदानुक्रम में विशेष रूप से मूल्यवान है जहाँ डेटा केवल कुछ लीफ नोड्स में आवश्यक है।

अक्सर पूछे जाने वाले प्रश्न

यदि Composition के दौरान State बदल दिया जाए तो क्या होगा

Composition के दौरान State बदलना एक नई पुनर्संरचना निर्धारित करता है, जो वर्तमान के पूरा होने के बाद निष्पादित होगी। कोई अनंत लूप नहीं होता: Compose गारंटी देता है कि प्रत्येक पुनर्संरचना snapshot सिस्टम के एक अलग लेन-देन में की जाती है।

जटिल स्क्रीन के Composition में कितना समय लगता है

आधुनिक उपकरणों पर, 50–100 Composable फ़ंक्शन वाली स्क्रीन का Composition 1–5 ms लेता है। Google 60fps फ्रेम के लिए 16 ms के भीतर रहने की सलाह देता है। यदि Composition इस सीमा से अधिक है, तो LazyColumn का उपयोग करें या स्क्रीन को छोटे फ़ंक्शन में विभाजित करें।

क्या Composition को मैन्युअल रूप से शुरू किया जा सकता है

Composition का सीधा मैन्युअल प्रारंभ संभव नहीं है — यह Composer द्वारा स्वचालित रूप से प्रबंधित किया जाता है। हालाँकि, आप State बदलकर या रूट composable पर invalidate() कॉल करके पुनर्संरचना को बाध्य कर सकते हैं यदि आपके पास CompositionContext तक पहुंच है।

क्लासिक Android में Composition View पदानुक्रम से कैसे भिन्न है

View पदानुक्रम Java ऑब्जेक्ट का एक अपरिवर्तनीय ट्री है जो एक बार बनाया जाता है। Composition एक आभासी ट्री है जो डेटा बदलने पर हर बार पुनर्निर्मित होता है। View अपनी स्थिति इंस्टेंस वेरिएबल में संग्रहीत करता है, Composition — फ़ंक्शन कॉल स्थिति से बंधे स्लॉट में।

Composition नोड हटाने को कैसे संभालता है

यदि कोई Composable फ़ंक्शन अब कॉल नहीं किया जाता है (उदाहरण के लिए, if शर्त false हो जाती है), Composition इसका नोड हटा देता है और DisposableEffect सफाई को ट्रिगर करता है। जब यह पुनः प्रकट होता है (if फिर से true हो जाता है), एक नया नोड बनाया जाता है — पुराना पुनर्स्थापित नहीं किया जाता है।

सारांश

  • Composition स्थिति से बंधे UI ट्री के निर्माण के लिए Composable फ़ंक्शन निष्पादित करने की प्रक्रिया है
  • Composer स्लॉट प्रबंधित करता है, फ़ंक्शन कॉल रिकॉर्ड करता है, और पुनर्संरचना के दौरान पैरामीटर की तुलना करता है
  • Snapshot सिस्टम State पर फ़ंक्शन निर्भरता पंजीकृत करता है और परिवर्तनों को लेन-देन में जोड़ता है
  • Composition प्रारंभ में एक बार निष्पादित होता है, Recomposition — डेटा बदलने पर
  • CompositionLocal स्पष्ट पैरामीटर श्रृंखला के बिना ट्री के माध्यम से कॉन्फ़िगरेशन डेटा पास करता है
  • स्थिति फ़ंक्शन कॉल संरचना ट्री में इसके अद्वितीय पहचानकर्ता के रूप में कार्य करती है
  • अनुशंसा: कुशल छोड़ने के लिए Composable फ़ंक्शन को अपरिवर्तनीय पैरामीटर के साथ छोटा रखें

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें