Element Tree — bu Flutter'dagi oraliq qatlam bo'lib, deklarativ Widget Tree'ni imperativ RenderObject Tree bilan bog'laydi. Har bir qayta qurishda qayta yaratiladigan vidjetlardan farqli o'laroq, elementlar yangilanishlar orasida saqlanadi va holat, kalitlar hamda hayotiy tsiklni boshqaradi. Flutter API Reference, 2025 ma'lumotlariga ko'ra, Element Tree'ni tushunish kalitlar bilan samarali ishlash, unumdorlikni optimallashtirish va vidjetlarning kutilmagan xatti-harakatlarini tuzatish uchun zarurdir.
Asosiy
Element Tree — bu Flutter'dagi oraliq iyerarxiya bo'lib, Widget Tree asosida yaratiladi va vidjetlarning ilovaga o'rnatilishini boshqaradi. Har bir element namunasi daraxtdagi bitta vidjetga mos keladi va unga havolani saqlaydi. Elementning vidjetdan asosiy farqi — element qayta qurishlar orasida daraxtdagi o'rnini saqlaydi, vidjet esa har bir build chaqiruvida qayta yaratilishi mumkin.
Element Tree bo'lmaganda, Flutter interfeysni samarali yangilay olmas edi. Agar har bir qayta qurish RenderObject Tree'ni qayta yaratsa, unumdorlik qabul qilib bo'lmaydigan darajada past bo'lar edi. Element Tree stabilizator rolini o'ynaydi: u yangilanishlar orasida RenderObject va State'ga havolalarni saqlaydi, bu Flutter'ga render daraxtiga faqat minimal o'zgarishlarni qo'llash imkonini beradi.
Flutter uchta asosiy element turidan foydalanadi: StatelessWidget uchun StatelessElement, StatefulWidget uchun StatefulElement va RenderObjectWidget uchun LeafRenderObjectElement, SingleChildRenderObjectElement, MultiChildRenderObjectElement. Har bir tur o'zining vidjet sinfi uchun ixtisoslashgan va elementning RenderObject bilan qanday aloqa qilishini belgilaydi.
Uch qatlamli arxitektura Flutter Widget Tree (konfiguratsiya), Element Tree (boshqaruv) va RenderObject Tree (chizish) dan iborat. Element Tree bog'lovchi bo'g'in hisoblanadi: u Widget'dan konfiguratsiyani o'qiydi va RenderObject'ga buyruqlarni uzatadi. Element Tree bo'lmaganda, freymvork deklarativ tavsifni haqiqiy chizish bilan samarali sinxronlashtira olmas edi.
Element daraxtga o'rnatilganda, u vidjet turini tekshiradi. Agar vidjet RenderObjectWidget bo'lsa, element tegishli RenderObject yaratadi va uni RenderObject Tree'ga qo'shadi. Agar vidjet LeafRenderObjectWidget bo'lsa, element barg RenderObject yaratadi. StatelessWidget va StatefulWidget uchun element shunchaki bolalar elementlarining o'rnatilishini boshqaradi.
abstract class Element {
Widget widget;
Element? parent;
List<Element>? children;
void mount(Element? parent, dynamic newSlot);
void update(Widget newWidget);
void unmount();
}
Ushbu soddalashtirilgan kod Element ning asosiy tuzilishini ko'rsatadi. Har bir element joriy vidjetga, ota-ona elementga va bola elementlarga havolani saqlaydi. Mount, update va unmount metodlari element va unga bog'liq RenderObject'ning hayotiy tsiklini boshqaradi.
Har bir element Flutter'da hayotiy tsiklning ketma-ket bosqichlaridan o'tadi: yaratish, o'rnatish, yangilash va olib tashlash. Ushbu bosqichlarni tushunish, ayniqsa animatsiyalar, asinxron operatsiyalar va holatni boshqarish bilan ishlashda kutilmagan xatti-harakatlarni tuzatish uchun zarurdir.
Element vidjetning createElement metodi chaqiruvi bilan yaratiladi. StatelessWidget uchun StatelessElement, StatefulWidget uchun StatefulElement (u State ob'ektini ham yaratadi) yaratiladi. RenderObjectWidget uchun tegishli RenderObjectElement yaratiladi. Element yaratish vidjet Widget Tree'da birinchi marta paydo bo'lganda sodir bo'ladi.
O'rnatishda element Element Tree'ga qo'shiladi va ota-ona elementni oladi. RenderObjectElement uchun o'rnatish RenderObject yaratadi va uni RenderObject Tree'ga joylashtiradi. Agar vidjet StatefulWidget bo'lsa, ushbu bosqichda State ob'ektining initState metodi chaqiriladi.
Vidjet yangi konfiguratsiya bilan qayta qurilganda, element update metodi orqali yangi vidjetni oladi. Element eski va yangi vidjet turini solishtiradi: agar turlar mos kelsa, element o'z konfiguratsiyasini yangilaydi; agar mos kelmasa — element olib tashlanadi va yangisi yaratiladi. Bu "vidjet almashinuvi" deb ataladi va tur o'zgarishida holatni yo'qotish sababidir.
Vidjet Widget Tree'dan o'chirilganda, elementning unmount metodi chaqiriladi. Element Element Tree'dan o'chiriladi, RenderObject RenderObject Tree'dan o'chiriladi va StatefulWidget uchun State ob'ektining dispose metodi chaqiriladi. Unmount'dan keyin element qayta ishlatilishi mumkin, agar vidjet xuddi shu pozitsiyada yana paydo bo'lsa.
Kalitlar (Key) — bu elementlarni identifikatsiya qilish mexanizmi bo'lib, Flutter'ga eski va yangi Widget Tree'dagi vidjetlarni pozitsiya bo'yicha emas, balki noyob identifikator bo'yicha moslashtirish imkonini beradi. Kalitlar elementlar tartibi o'zgarishi mumkin bo'lgan dinamik ro'yxatlar bilan ishlashda juda muhim: elementlarni qo'shish, o'chirish yoki qayta tartiblash.
Kalitsiz Flutter elementlarni ularning pozitsiyasi bo'yicha moslashtiradi: eski daraxtdagi 0-pozitsiyadagi element yangi daraxtdagi 0-pozitsiyadagi vidjet bilan almashtiriladi. Agar tartib o'zgargan bo'lsa, elementlar aralashib ketadi va holat yo'qolishi yoki noto'g'ri ma'lumotlarga bog'lanishi mumkin. Kalit Flutter'ni elementni pozitsiya bo'yicha emas, balki identifikator bo'yicha izlashga majbur qiladi.
ValueKey elementni identifikatsiya qilish uchun oddiy qiymatdan (satr, raqam) foydalanadi. ObjectKey ob'ektga havoladan foydalanadi — element barqaror satr identifikatoriga ega bo'lmaganda mos keladi. UniqueKey har bir yaratishda noyob identifikator yaratadi — vidjetning har bir namunasi noyob bo'lishi kerak bo'lganda ishlatiladi.
Column(
children: items.map((item) => TodoItem(
key: ValueKey(item.id),
title: item.title,
isDone: item.isDone,
)).toList(),
)
Ushbu misolda item.id bilan ValueKey har bir TodoItem o'z holatini (masalan, kiritish maydoni fokusi) ro'yxatdagi elementlar tartibi o'zgarganida saqlab qolishini kafolatlaydi. Kalitsiz birinchi pozitsiyadagi element o'sha pozitsiyadagi oldingi elementning holatini olgan bo'lar edi.
Holat (State) Flutter'da vidjetlarda emas, balki elementlarda saqlanadi. StatefulWidget qayta qurilganda va vidjetning yangi namunasini yaratganda, tegishli StatefulElement eski State ob'ektiga havolani saqlaydi. Yangi vidjet mavjud State bilan bog'lanadi, bu qayta qurishlar orasida ma'lumotlarni saqlash imkonini beradi.
Vidjet qayta qurilganda Flutter yangi StatefulWidget namunasini yaratadi, ammo tegishli StatefulElement Element Tree'da qoladi. Element State'ning update metodini chaqiradi, yangi vidjetni uzatadi. Shunday qilib, State ob'ekti va uning ma'lumotlari saqlanadi. Holat yo'qolishi faqat vidjet turi o'zgarganda, kalit o'zgarganda yoki element daraxtdan o'chirilganda sodir bo'ladi.
InheritedElement — bu maxsus element bo'lib, bola elementlarga konstruktorlar orqali aniq uzatmasdan ota-ona InheritedWidget'dan ma'lumot olish imkonini beradi. InheritedWidget o'zgarganda, InheritedElement barcha bog'liq elementlarni xabardor qiladi, ular qayta quriladi. Ushbu mexanizm Theme, MediaQuery va Provider asosida yotadi.
Element Tree xotirani iste'mol qiladi va birinchi renderlash tezligiga ta'sir qiladi. Har bir element ma'lum hajmdagi xotirani egallaydi: vidjetga havola, ota-onaga havola, bola elementlar ro'yxati, slot va RenderObjectElement uchun qo'shimcha maydonlar. Element Tree'ni optimallashtirish ishga tushirish vaqtini kamaytiradi va xotira iste'molini pasaytiradi.
Flutter qayta qurishda elementlarni qayta ishlatishga harakat qiladi. Agar yangi konfiguratsiyadagi vidjet bir xil tur va kalitga ega bo'lsa, element qayta yaratilmaydi — u yangilanadi. Bu yangi element yaratish va keyin o'rnatishdan ancha tezdir. Biroq, tur yoki kalit o'zgarganda eski element olib tashlanadi va yangisi noldan yaratiladi.
RepaintBoundary RenderObject Tree'da alohida RenderRepaintBoundary yaratadi, u daraxtning bir qismini izolyatsiya qiladi. Element Tree darajasida RepaintBoundary maxsus element yaratmaydi — u SingleChildRenderObjectElement'dan foydalanadi. Farq RenderObject darajasida namoyon bo'ladi: RepaintBoundary tarkibi o'zgarganda faqat izolyatsiya qilingan hudud qayta chiziladi.
| Operatsiya | RepaintBoundary'siz | RepaintBoundary bilan |
|---|---|---|
| Qayta chizish | Butun ekran | Faqat izolyatsiya qilingan hudud |
| Vaqt | ~16 ms 60 FPS da | ~2-5 ms |
| Xotira | Minimal | + bir necha kilobayt qatlam uchun |
Jadval ko'rsatganidek, RepaintBoundary o'zgaruvchan hududni izolyatsiya qilish orqali qayta chizish vaqtini sezilarli darajada qisqartiradi. Element Tree darajasida bu qo'shimcha konfiguratsiyani talab qilmaydi — o'zgaruvchan vidjetni RepaintBoundary bilan o'rash kifoya.
Tez-tez beriladigan savollar
Widget Tree — bu har bir qayta qurishda qayta yaratiladigan konfiguratsiya. Element Tree — yangilanishlar orasida saqlanadigan va vidjetlarning holati, RenderObject va hayotiy tsiklini boshqaradigan doimiy struktura.
Element Tree bo'lmaganda Flutter har bir holat o'zgarishida RenderObject Tree'ni qayta yaratishga majbur bo'lar edi, bu sezilarli kechikishlarga olib kelardi. Element Tree RenderObject va State'ni saqlaydi, faqat minimal o'zgarishlarni qo'llash imkonini beradi.
Element tegishli vidjet Widget Tree'dan yo'qolganda yoki vidjet turi (masalan, Column Row bilan almashtirilganda) yoki kalit o'zgarganda o'chiriladi. Olib tashlashda State'ning dispose metodi chaqiriladi.
Kalitlar moslashtirish algoritmini o'zgartiradi: elementni pozitsiya bo'yicha qidirish o'rniga Flutter elementni kalit qiymati bo'yicha qidiradi. Bu vidjetlar tartibi yoki soni o'zgarganda holatni saqlash imkonini beradi.
Ha, BuildContext orqali, bu elementning abstraksiyasidir. findAncestorWidgetOfExactType va dependOnInheritedWidgetOfExactType metodlari Element Tree bilan ishlaydi, elementlar daraxti bo'ylab yuqoriga ko'tariladi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.