Element Tree Flutter में एक मध्यवर्ती परत है जो घोषणात्मक Widget Tree को अनिवार्य RenderObject Tree से जोड़ती है। विजेट्स के विपरीत, जो हर पुनर्निर्माण पर फिर से बनाए जाते हैं, तत्व अपडेट के बीच बने रहते हैं और स्थिति, कुंजियों और जीवनचक्र का प्रबंधन करते हैं। Flutter API Reference, 2025 के अनुसार, कुंजियों के साथ प्रभावी ढंग से काम करने, प्रदर्शन अनुकूलन और विजेट्स के अप्रत्याशित व्यवहार को डीबग करने के लिए Element Tree को समझना आवश्यक है।
मुख्य बातें
Element Tree Flutter में एक मध्यवर्ती पदानुक्रम है जो Widget Tree के आधार पर बनाया जाता है और एप्लिकेशन में विजेट्स के सम्मिलन का प्रबंधन करता है। प्रत्येक तत्व उदाहरण ट्री में एक विजेट से मेल खाता है और उसका संदर्भ संग्रहीत करता है। तत्व और विजेट के बीच मुख्य अंतर यह है कि तत्व पुनर्निर्माण के बीच ट्री में अपनी स्थिति बनाए रखता है, जबकि विजेट हर build कॉल पर पुनः बनाया जा सकता है।
Element Tree के बिना, Flutter कुशलतापूर्वक UI को अपडेट नहीं कर सकता। यदि प्रत्येक पुनर्निर्माण RenderObject Tree को फिर से बनाता, तो प्रदर्शन अस्वीकार्य रूप से कम होता। Element Tree एक स्थिरक के रूप में कार्य करता है: यह अपडेट के बीच RenderObject और State के संदर्भों को बनाए रखता है, जिससे Flutter केवल न्यूनतम परिवर्तनों को रेंडर ट्री पर लागू कर सकता है।
Flutter तीन मुख्य प्रकार के तत्वों का उपयोग करता है: StatelessElement StatelessWidget के लिए, StatefulElement StatefulWidget के लिए, और LeafRenderObjectElement, SingleChildRenderObjectElement, MultiChildRenderObjectElement RenderObjectWidget के लिए। प्रत्येक प्रकार अपने विजेट वर्ग के लिए विशिष्ट है और यह निर्धारित करता है कि तत्व RenderObject के साथ कैसे इंटरैक्ट करता है।
तीन-परत वास्तुकला Flutter में Widget Tree (कॉन्फ़िगरेशन), Element Tree (प्रबंधन) और RenderObject Tree (रेंडरिंग) से मिलकर बनी है। Element Tree कड़ी है: यह Widget से कॉन्फ़िगरेशन पढ़ता है और RenderObject को कमांड भेजता है। Element Tree के बिना, फ्रेमवर्क घोषणात्मक विवरण को वास्तविक रेंडरिंग के साथ कुशलतापूर्वक सिंक्रनाइज़ नहीं कर सकता।
जब कोई तत्व ट्री में स्थापित होता है, तो वह विजेट प्रकार की जाँच करता है। यदि विजेट RenderObjectWidget है, तो तत्व संबंधित RenderObject बनाता है और इसे RenderObject Tree में जोड़ता है। यदि विजेट LeafRenderObjectWidget है, तो तत्व एक लीफ RenderObject बनाता है। StatelessWidget और StatefulWidget के लिए, तत्व केवल चाइल्ड तत्वों के सम्मिलन का प्रबंधन करता है।
abstract class Element {
Widget widget;
Element? parent;
List<Element>? children;
void mount(Element? parent, dynamic newSlot);
void update(Widget newWidget);
void unmount();
}
यह सरलीकृत कोड Element की मूल संरचना दिखाता है। प्रत्येक तत्व वर्तमान विजेट, पैरेंट तत्व और चाइल्ड तत्वों का संदर्भ संग्रहीत करता है। mount, update और unmount विधियाँ तत्व और उससे जुड़े RenderObject के जीवनचक्र का प्रबंधन करती हैं।
प्रत्येक तत्व Flutter में जीवनचक्र के चरणों के अनुक्रम से गुज़रता है: निर्माण, स्थापना, अद्यतन और विस्थापन। इन चरणों को समझना अप्रत्याशित व्यवहार को डीबग करने के लिए आवश्यक है, विशेष रूप से एनिमेशन, अतुल्यकालिक संचालन और स्थिति प्रबंधन के साथ काम करते समय।
एक तत्व विजेट की createElement विधि को कॉल करके बनाया जाता है। StatelessWidget के लिए StatelessElement बनाया जाता है; StatefulWidget के लिए StatefulElement बनाया जाता है (जो एक State ऑब्जेक्ट भी बनाता है)। RenderObjectWidget के लिए संबंधित RenderObjectElement बनाया जाता है। तत्व निर्माण तब होता है जब विजेट पहली बार Widget Tree में दिखाई देता है।
स्थापना के दौरान, तत्व Element Tree में जोड़ा जाता है और एक पैरेंट तत्व प्राप्त करता है। RenderObjectElement के लिए, स्थापना एक RenderObject भी बनाती है और इसे RenderObject Tree में सम्मिलित करती है। यदि विजेट StatefulWidget है, तो इस चरण पर State ऑब्जेक्ट की initState विधि कॉल की जाती है।
जब विजेट नए कॉन्फ़िगरेशन के साथ पुनर्निर्मित होता है, तो तत्व update विधि के माध्यम से नया विजेट प्राप्त करता है। तत्व पुराने और नए विजेट के प्रकार की तुलना करता है: यदि प्रकार मेल खाते हैं, तो तत्व अपना कॉन्फ़िगरेशन अपडेट करता है; यदि नहीं, तो तत्व विस्थापित हो जाता है और एक नया बनाया जाता है। इसे "विजेट परिवर्तन" कहा जाता है और प्रकार बदलने पर स्थिति हानि का कारण है।
जब विजेट Widget Tree से हटा दिया जाता है, तो तत्व की unmount विधि कॉल की जाती है। तत्व Element Tree से हटा दिया जाता है, RenderObject RenderObject Tree से हटा दिया जाता है, और StatefulWidget के लिए State ऑब्जेक्ट की dispose विधि कॉल की जाती है। विस्थापन के बाद, तत्व का पुनः उपयोग किया जा सकता है यदि विजेट फिर से उसी स्थिति में दिखाई देता है।
कुंजियाँ (Key) तत्व पहचान तंत्र हैं जो Flutter को पुराने और नए Widget Tree से विजेट्स का मिलान स्थिति से नहीं, बल्कि एक अद्वितीय पहचानकर्ता द्वारा करने की अनुमति देती हैं। कुंजियाँ गतिशील सूचियों के साथ काम करते समय अत्यंत महत्वपूर्ण हैं जहाँ तत्वों का क्रम बदल सकता है: तत्वों को जोड़ना, हटाना या पुनर्व्यवस्थित करना।
कुंजी के बिना, Flutter तत्वों का मिलान ट्री में उनकी स्थिति से करता है: पुराने ट्री से स्थिति 0 पर तत्व को नए ट्री से स्थिति 0 पर विजेट से बदल दिया जाता है। यदि क्रम बदल गया है, तो तत्व मिश्रित हो जाते हैं और स्थिति खो सकती है या गलत डेटा से बंध सकती है। एक कुंजी Flutter को स्थिति के बजाय पहचानकर्ता द्वारा तत्व खोजने के लिए मजबूर करती है।
ValueKey तत्व की पहचान करने के लिए एक सरल मान (स्ट्रिंग, संख्या) का उपयोग करता है। ObjectKey एक ऑब्जेक्ट संदर्भ का उपयोग करता है — तब उपयुक्त जब तत्व के पास स्थिर स्ट्रिंग पहचानकर्ता न हो। UniqueKey प्रत्येक निर्माण पर एक अद्वितीय पहचानकर्ता उत्पन्न करता है — तब उपयोग किया जाता है जब प्रत्येक विजेट उदाहरण अद्वितीय होना चाहिए।
Column(
children: items.map((item) => TodoItem(
key: ValueKey(item.id),
title: item.title,
isDone: item.isDone,
)).toList(),
)
इस उदाहरण में, item.id के साथ ValueKey सुनिश्चित करता है कि सूची में तत्वों का क्रम बदलने पर प्रत्येक TodoItem अपनी स्थिति (जैसे, इनपुट फ़ील्ड फ़ोकस) बनाए रखता है। कुंजी के बिना, पहली स्थिति पर तत्व उसी स्थिति पर पिछले तत्व की स्थिति प्राप्त करता।
स्थिति (State) Flutter में विजेट्स में नहीं, बल्कि तत्वों में संग्रहीत होती है। जब StatefulWidget पुनर्निर्मित होता है और एक नया विजेट उदाहरण बनाता है, तो संबंधित StatefulElement पुराने State ऑब्जेक्ट का संदर्भ बनाए रखता है। नया विजेट मौजूदा State से जुड़ता है, जिससे पुनर्निर्माण के बीच डेटा संरक्षित रहता है।
विजेट पुनर्निर्माण के दौरान, Flutter StatefulWidget का एक नया उदाहरण बनाता है, लेकिन संबंधित StatefulElement Element Tree में रहता है। तत्व State पर update विधि कॉल करता है, नया विजेट पास करता है। इस प्रकार, State ऑब्जेक्ट और उसका डेटा संरक्षित रहता है। स्थिति हानि केवल तब होती है जब विजेट प्रकार बदलता है, कुंजी बदलती है, या तत्व ट्री से हटा दिया जाता है।
InheritedElement एक विशेष तत्व है जो चाइल्ड तत्वों को कंस्ट्रक्टर के माध्यम से स्पष्ट पासिंग के बिना पैरेंट InheritedWidget से डेटा प्राप्त करने की अनुमति देता है। जब InheritedWidget बदलता है, InheritedElement सभी आश्रित तत्वों को सूचित करता है, जो फिर पुनर्निर्मित होते हैं। यह तंत्र Theme, MediaQuery और Provider का आधार है।
Element Tree मेमोरी की खपत करता है और पहली रेंडरिंग गति को प्रभावित करता है। प्रत्येक तत्व एक निश्चित मात्रा में मेमोरी लेता है: विजेट का संदर्भ, पैरेंट का संदर्भ, चाइल्ड तत्वों की सूची, एक स्लॉट और RenderObjectElement के लिए अतिरिक्त फ़ील्ड। Element Tree को अनुकूलित करने से स्टार्टअप समय कम होता है और मेमोरी खपत घटती है।
Flutter पुनर्निर्माण के दौरान तत्वों को पुनः उपयोग करने का प्रयास करता है। यदि नए कॉन्फ़िगरेशन में विजेट का समान प्रकार और कुंजी है, तो तत्व पुनः नहीं बनाया जाता — इसे अपडेट किया जाता है। यह नए तत्व को बनाने और उसे स्थापित करने की तुलना में काफी तेज़ है। हालाँकि, जब प्रकार या कुंजी बदलती है, तो पुराना तत्व विस्थापित हो जाता है और नया स्क्रैच से बनाया जाता है।
RepaintBoundary RenderObject Tree में एक अलग RenderRepaintBoundary बनाता है जो ट्री के भाग को अलग करता है। Element Tree स्तर पर, RepaintBoundary कोई विशेष तत्व नहीं बनाता — यह SingleChildRenderObjectElement का उपयोग करता है। अंतर RenderObject स्तर पर दिखाई देता है: जब RepaintBoundary सामग्री बदलती है, तो केवल पृथक क्षेत्र को फिर से रंगा जाता है।
| संक्रिया | RepaintBoundary के बिना | RepaintBoundary के साथ |
|---|---|---|
| पुनः रंगाई | पूरी स्क्रीन | केवल पृथक क्षेत्र |
| समय | ~16 ms 60 FPS पर | ~2-5 ms |
| मेमोरी | न्यूनतम | + कुछ किलोबाइट प्रति परत |
जैसा कि तालिका दिखाती है, RepaintBoundary बदलते क्षेत्र को अलग करके पुनः रंगाई के समय को काफी कम करता है। Element Tree स्तर पर, इसके लिए किसी अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता नहीं है — बस बदलते विजेट को RepaintBoundary में लपेटें।
अक्सर पूछे जाने वाले प्रश्न
Widget Tree एक कॉन्फ़िगरेशन है जो प्रत्येक पुनर्निर्माण पर फिर से बनाया जाता है। Element Tree एक स्थायी संरचना है जो अपडेट के बीच बनी रहती है और स्थिति, RenderObject और विजेट जीवनचक्र का प्रबंधन करती है।
Element Tree के बिना, Flutter को प्रत्येक स्थिति परिवर्तन पर RenderObject Tree को फिर से बनाना पड़ता, जिससे महत्वपूर्ण देरी होती। Element Tree RenderObject और State को संरक्षित करता है, जिससे केवल न्यूनतम परिवर्तन लागू किए जा सकते हैं।
एक तत्व तब हटाया जाता है जब संबंधित विजेट Widget Tree से गायब हो जाता है, या जब विजेट प्रकार बदलता है (जैसे, Column को Row से बदलना) या कुंजी बदलती है। विस्थापन पर State पर dispose कॉल किया जाता है।
कुंजियाँ मिलान एल्गोरिथ्म बदलती हैं: स्थिति से तत्व खोजने के बजाय, Flutter कुंजी मान से तत्व खोजता है। यह विजेट्स के क्रम या मात्रा बदलने पर स्थिति को संरक्षित करने की अनुमति देता है।
हाँ, BuildContext के माध्यम से, जो तत्व का एक अमूर्तन है। findAncestorWidgetOfExactType और dependOnInheritedWidgetOfExactType विधियाँ Element Tree के साथ काम करती हैं, तत्व ट्री में ऊपर जाती हैं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें