Element Tree Flutter-də deklarativ Widget Tree ilə imperativ RenderObject Tree arasında əlaqə quran ara təbəqədir. Hər rebuild zamanı yenidən yaradılan vidcetlərdən fərqli olaraq, elementlər yeniləmələr arasında saxlanılır və vəziyyəti, açarları və həyat dövrünü idarə edir. Flutter API Reference, 2025-a görə, Element Tree-nin başa düşülməsi açarlarla effektiv işləmək, performansı optimallaşdırmaq və vidcetlərin gözlənilməz davranışını aradan qaldırmaq üçün zəruridir.
Əsas məqamlar
Element Tree Flutter-də Widget Tree əsasında yaradılan və vidcetlərin tətbiqə yerləşdirilməsini idarə edən ara iyerarxiyadır. Elementin hər bir nümunəsi ağacdakı bir vidcetə uyğun gəlir və ona istinad saxlayır. Elementin vidcetdən əsas fərqi ondan ibarətdir ki, element yenidən qurulmalar arasında ağacdakı mövqeyini saxlayır, vidcet isə hər build çağırışında yenidən yaradıla bilər.
Element Tree olmadan Flutter interfeysi effektiv yeniləyə bilməzdi. Əgər hər rebuild RenderObject Tree-ni yenidən yaratsaydı, performans qəbuledilməz dərəcədə aşağı olardı. Element Tree stabilizator rolunu oynayır: yeniləmələr arasında RenderObject və State-ə istinadları saxlayır və Flutter-ə rəsm ağacına yalnız minimal dəyişikliklər tətbiq etməyə imkan verir.
Flutter üç əsas element növündən istifadə edir: StatelessWidget üçün StatelessElement, StatefulWidget üçün StatefulElement və RenderObjectWidget üçün LeafRenderObjectElement, SingleChildRenderObjectElement, MultiChildRenderObjectElement. Hər növ öz vidcet sinfi üçün ixtisaslaşıb və elementin RenderObject ilə necə qarşılıqlı əlaqədə olduğunu müəyyən edir.
Üç qatlı arxitektura Flutter Widget Tree (konfiqurasiya), Element Tree (idarəetmə) və RenderObject Tree-dən (rəsm) ibarətdir. Element Tree əlaqələndirici halqadır: o, konfiqurasiyanı Widget-dən oxuyur və əmrləri RenderObject-ə ötürür. Element Tree olmadan freymvork deklarativ təsviri faktiki rəsmlə effektiv sinxronlaşdıra bilməzdi.
Element ağaca yerləşdirilərkən vidcetin növünü yoxlayır. Əgər vidcet RenderObjectWidget-dürsə, element müvafiq RenderObject yaradır və onu RenderObject Tree-yə əlavə edir. Əgər vidcet LeafRenderObjectWidget-dirsə, element yarpaq RenderObject yaradır. StatelessWidget və StatefulWidget üçün element sadəcə uşaq elementlərin yerləşdirilməsini idarə edir.
abstract class Element {
Widget widget;
Element? parent;
List<Element>? children;
void mount(Element? parent, dynamic newSlot);
void update(Widget newWidget);
void unmount();
}
Bu sadələşdirilmiş kod Element-in əsas strukturunu göstərir. Hər element cari vidcetə, valideyn elementə və uşaq elementlərə istinad saxlayır. mount və update metodları elementin və onunla əlaqəli RenderObject-un həyat dövrünü idarə edir.
Hər element Flutter-də həyat dövrünün ardıcıl mərhələlərindən keçir: yaradılma, montaj, yeniləmə və demontaj. Bu mərhələləri başa düşmək, xüsusən animasiyalar, asinxron əməliyyatlar və vəziyyətin idarə edilməsi ilə işləyərkən gözlənilməz davranışın aradan qaldırılması üçün zəruridir.
Element vidcetin createElement metodunun çağırılması ilə yaradılır. StatelessWidget üçün StatelessElement, StatefulWidget üçün isə StatefulElement yaradılır (o, həmçinin State obyektini yaradır). RenderObjectWidget üçün müvafiq RenderObjectElement yaradılır. Elementin yaradılması vidcet Widget Tree-də ilk dəfə görünəndə baş verir.
Montaj zamanı element Element Tree-yə əlavə olunur və valideyn elementi alır. RenderObjectElement üçün montaj həmçinin RenderObject yaradır və onu RenderObject Tree-yə yerləşdirir. Əgər vidcet StatefulWidget-dirsə, bu mərhələdə State obyektinin initState metodu çağırılır.
Vidcet yeni konfiqurasiya ilə yenidən qurulduqda element update metodu vasitəsilə yeni vidceti alır. Element yeni və köhnə vidcetin növünü müqayisə edir: əgər növlər üst-üstə düşürsə, element öz konfiqurasiyasını yeniləyir; əgər yox — element demontaj edilir və yenisi yaradılır. Bu, „vidcetin dəyişdirilməsi" adlanır və növün dəyişdirilməsi zamanı vəziyyətin itirilməsinin səbəbidir.
Vidcet Widget Tree-dən silinərkən elementdə unmount metodu çağırılır. Element Element Tree-dən, RenderObject isə RenderObject Tree-dən silinir, StatefulWidget üçün isə State obyektinin dispose metodu çağırılır. Unmount-dan sonra vidcet yenidən eyni mövqedə görünsə, element yenidən istifadə oluna bilər.
Açarlar (Key) elementləri identifikasiya etmək mexanizmidir və Flutter-ə köhnə və yeni Widget Tree-dən vidcetləri mövqeyə görə deyil, unikal identifikatora görə uyğunlaşdırmağa imkan verir. Açarlar elementlərin sırasının dəyişə biləcəyi dinamik siyahılarla işləyərkən kritik əhəmiyyət daşıyır: elementlərin əlavə edilməsi, silinməsi və ya yenidən yerləşdirilməsi.
Açar olmadan Flutter elementləri onların ağacdakı mövqeyinə görə uyğunlaşdırır: köhnə ağacın 0 mövqeyindəki element yeni ağacın 0 mövqeyindəki vidcetlə əvəz olunur. Əgər sıra dəyişibsə, elementlər qarışır və vəziyyət itirilə və ya səhv məlumatlara bağlana bilər. Açar Flutter-i elementi mövqeyə görə deyil, identifikatora görə axtarmağa məcbur edir.
ValueKey elementi identifikasiya etmək üçün sadə dəyərdən (sətir, ədəd) istifadə edir. ObjectKey obyektə istinaddan istifadə edir — elementin stabil sətir identifikatoru olmadıqda uyğundur. UniqueKey hər yaradılmada unikal identifikator generasiya edir — hər vidcet nümunəsi unikal olmalı olduqda istifadə olunur.
Column(
children: items.map((item) => TodoItem(
key: ValueKey(item.id),
title: item.title,
isDone: item.isDone,
)).toList(),
)
Bu nümunədə ValueKey item.id ilə siyahıda elementlərin sırası dəyişərkən hər TodoItem-in öz vəziyyətini (məsələn, daxiletmə sahəsinin fokusunu) saxlamasını təmin edir. Açar olmadan birinci mövqedəki element əvvəlki elementin həmin mövqedəki vəziyyətini alardı.
Vəziyyət (State) Flutter-də vidcetlərdə deyil, elementlərdə saxlanılır. StatefulWidget yenidən qurularaq vidcetin yeni nümunəsini yaradanda müvafiq StatefulElement köhnə State obyektinə istinadı saxlayır. Yeni vidcet mövcud State ilə əlaqələnir və bu, məlumatları yenidən qurulmalar arasında saxlamağa imkan verir.
Vidcetin rebuild-i zamanı Flutter StatefulWidget-in yeni nümunəsini yaradır, lakin müvafiq StatefulElement Element Tree-də qalır. Element State-də update metodunu çağıraraq yeni vidceti ötürür. Beləliklə, State obyekti və onun məlumatları saxlanılır. Vəziyyətin itirilməsi yalnız vidcetin növü dəyişdikdə, açar dəyişdikdə və ya element ağacdan silindikdə baş verir.
InheritedElement uşaq elementlərə konstruktorlar vasitəsilə aşkar ötürmədən valideyn InheritedWidget-dən məlumat almağa imkan verən xüsusi elementdir. InheritedWidget dəyişəndə InheritedElement bütün asılı elementləri xəbərdar edir və onlar yenidən qurulur. Bu mexanizm Theme, MediaQuery və Provider-in əsasını təşkil edir.
Element Tree yaddaş istehlak edir və ilk rəsm sürətinə təsir göstərir. Hər element müəyyən yaddaş həcmi tutur: vidcetə istinad, valideynə istinad, uşaq elementlərin siyahısı, slot və RenderObjectElement üçün əlavə sahələr. Element Tree-nin optimallaşdırılması işə salınma vaxtını azaldır və yaddaş istehlakını kiçildir.
Flutter yenidən qurulma zamanı elementləri yenidən istifadə etməyə çalışır. Əgər yeni konfiqurasiyadakı vidcet eyni növə və açar sahibdirsə, element yenidən yaradılmır — o, yenilənir. Bu, sonradan montaj edilən yeni elementin yaradılmasından xeyli sürətlidir. Lakin növ və ya açar dəyişdikdə köhnə element demontaj edilir, yenisi isə sıfırdan yaradılır.
RepaintBoundary RenderObject Tree-də ağacın bir hissəsini təcrid edən ayrıca RenderRepaintBoundary yaradır. Element Tree səviyyəsində RepaintBoundary xüsusi element yaratmır — o, SingleChildRenderObjectElement-dən istifadə edir. Fərq RenderObject səviyyəsində özünü göstərir: RepaintBoundary-nin məzmunu dəyişəndə yalnız təcrid olunmuş sahə yenidən rənglənir.
| Əməliyyat | RepaintBoundary olmadan | RepaintBoundary ilə |
|---|---|---|
| Yenidən rəngləmə | Bütün ekran | Yalnız təcrid olunmuş sahə |
| Vaxt | 60 FPS-də ~16 ms | ~2-5 ms |
| Yaddaş | Minimal | + təbəqə başına bir neçə kilobayt |
Cədvəl göstərir ki, RepaintBoundary dəyişən sahənin təcrid edilməsi hesabına yenidən rəngləmə vaxtını əhəmiyyətli dərəcədə azaldır. Element Tree səviyyəsində bu, əlavə konfiqurasiya tələb etmir — dəyişən vidceti RepaintBoundary-ə bükmək kifayətdir.
Tez-tez verilən suallar
Widget Tree hər rebuild zamanı yenidən yaradılan konfiqurasiyadır. Element Tree isə yeniləmələr arasında saxlanılan və vidcetlərin vəziyyətini, RenderObject-u və həyat dövrünü idarə edən sabit strukturdur.
Element Tree olmadan Flutter hər vəziyyət dəyişikliyində RenderObject Tree-ni yenidən yaratmalı olardı və bu, əhəmiyyətli gecikmələrə səbəb olardı. Element Tree RenderObject və State-i saxlayaraq yalnız minimal dəyişikliklərin tətbiqinə imkan verir.
Element, müvafiq vidcet Widget Tree-dən yox olduqda və ya vidcetin növü (məsələn, Column Row ilə əvəz olunduqda) və ya açar dəyişdikdə silinir. Demontaj zamanı State-də dispose çağırılır.
Açarlar uyğunlaşdırma alqoritmini dəyişir: Flutter elementi mövqeyə görə yox, açarın dəyərinə görə axtarır. Bu, vidcetlərin sırası və ya sayı dəyişərkən vəziyyəti saxlamağa imkan verir.
Bəli, elementin abstraksiyası olan BuildContext vasitəsilə. findAncestorWidgetOfExactType və dependOnInheritedWidgetOfExactType metodları Element Tree üzərində işləyir və elementlər ağacı üzrə yuxarı qalxır.
Nəticələr
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun