Element Tree: nedir, RenderObject ile ilişkisi ve çalışma prensibi

Yazar: IT Sectr Yayınlanma: 2026-07-01 Okuma süresi: 10 dk

Element Tree, Flutter'da bildirimsel Widget Tree ile zorunlu RenderObject Tree'yi birbirine bağlayan bir ara katmandır. Her yeniden yapılandırmada yeniden oluşturulan widget'ların aksine, öğeler güncellemeler arasında kalıcı olur ve durum, anahtarlar ve yaşam döngüsünü yönetir. Flutter API Reference, 2025'e göre, Element Tree'yi anlamak, anahtarlarla etkili çalışmak, performansı optimize etmek ve beklenmeyen widget davranışlarını hata ayıklamak için gereklidir.

Önemli Noktalar

  • Element Tree — Widget ve RenderObject ağaçları arasında yeniden yapılandırmalar arasında kalan kalıcı bir katmandır.
  • Her widget, ağaca yerleştirilmesini ve yaşam döngüsünü yöneten bir öğe oluşturur.
  • StatefulElement, widget yeniden oluşturulduktan sonra bile erişilebilir olan bir State nesnesi saklar.
  • Anahtarlar (Key), Element Tree düzeyinde çalışarak yeniden yapılandırma sırasında widget'ların eşleştirilmesine yardımcı olur.
  • Element Tree, doğrudan RenderObject Tree'ye bağlıdır — her öğe bir RenderObject oluşturabilir veya kaldırabilir.

Flutter'da Element Tree Nedir?

Element Tree, Widget Tree temel alınarak oluşturulan ve widget'ların uygulamaya yerleştirilmesini yöneten Flutter'daki bir ara hiyerarşidir. Her öğe örneği, ağaçtaki bir widget'a karşılık gelir ve ona bir referans saklar. Bir öğe ile widget arasındaki temel fark, öğenin yeniden yapılandırmalar arasında ağaçtaki konumunu koruması, oysa widget'ın her build çağrısında yeniden oluşturulabilmesidir.

Element Tree Neden Gereklidir

Element Tree olmadan, Flutter kullanıcı arayüzünü verimli bir şekilde güncelleyemezdi. Her yeniden yapılandırma RenderObject Tree'yi yeniden oluştursaydı, performans kabul edilemez derecede düşük olurdu. Element Tree bir dengeleyici görevi görür: güncellemeler arasında RenderObject ve State'e referansları tutar ve Flutter'ın render ağacına yalnızca minimum değişiklikleri uygulamasına izin verir.

Öğe Türleri

Flutter üç ana öğe türü kullanır: StatelessWidget için StatelessElement, StatefulWidget için StatefulElement ve RenderObjectWidget için LeafRenderObjectElement, SingleChildRenderObjectElement, MultiChildRenderObjectElement. Her tür, widget sınıfı için uzmanlaşmıştır ve öğenin RenderObject ile nasıl etkileşime gireceğini belirler.

Üç Katmanlı Mimaride Widget, Element ve RenderObject Arasındaki İlişki

Üç katmanlı mimari, Flutter'da Widget Tree (yapılandırma), Element Tree (yönetim) ve RenderObject Tree (render) olmak üzere üç katmandan oluşur. Element Tree bağlantı halkasıdır: Widget'tan yapılandırmayı okur ve RenderObject'a komutlar iletir. Element Tree olmadan, çerçeve bildirimsel tanımı gerçek render ile verimli bir şekilde senkronize edemezdi.

Öğe, Widget ve RenderObject'u Nasıl Bağlar

Bir öğe ağaca monte edildiğinde, widget türünü kontrol eder. Widget bir RenderObjectWidget ise, öğe ilgili RenderObject'u oluşturur ve RenderObject Tree'ye ekler. Widget bir LeafRenderObjectWidget ise, öğe bir yaprak RenderObject oluşturur. StatelessWidget ve StatefulWidget için öğe yalnızca alt öğelerin montajını yönetir.

dart
abstract class Element {
  Widget widget;
  Element? parent;
  List<Element>? children;

  void mount(Element? parent, dynamic newSlot);
  void update(Widget newWidget);
  void unmount();
}

Bu basitleştirilmiş kod, Element'in temel yapısını gösterir. Her öğe, geçerli widget'a, üst öğeye ve alt öğelere bir referans saklar. mount, update ve unmount yöntemleri, öğenin ve ilişkili RenderObject'unun yaşam döngüsünü yönetir.

Öğe Yaşam Döngüsü: Oluşturmadan Kaldırmaya

Her öğe Flutter'da bir dizi yaşam döngüsü aşamasından geçer: oluşturma, monte etme, güncelleme ve monte etmeme. Bu aşamaları anlamak, özellikle animasyonlar, asenkron işlemler ve durum yönetimi ile çalışırken beklenmeyen davranışlarda hata ayıklamak için gereklidir.

Aşama 1: Öğe Oluşturma

Bir öğe, widget'ın createElement yöntemi çağrılarak oluşturulur. StatelessWidget için bir StatelessElement oluşturulur; StatefulWidget için bir StatefulElement (ayrıca bir State nesnesi oluşturur) oluşturulur. RenderObjectWidget için ilgili RenderObjectElement oluşturulur. Öğe oluşturma, widget Widget Tree'de ilk kez göründüğünde gerçekleşir.

Aşama 2: Monte Etme (mount)

Monte etme sırasında, öğe Element Tree'ye eklenir ve bir üst öğe alır. RenderObjectElement için monte etme ayrıca bir RenderObject oluşturur ve onu RenderObject Tree'ye ekler. Widget bir StatefulWidget ise, bu aşamada State nesnesinin initState yöntemi çağrılır.

Aşama 3: Güncelleme (update)

Widget yeni bir yapılandırmayla yeniden oluşturulduğunda, öğe yeni widget'ı update yöntemi aracılığıyla alır. Öğe, eski ve yeni widget'ın türünü karşılaştırır: türler eşleşirse, öğe yapılandırmasını günceller; eşleşmezse, öğe monte edilmez ve yeni bir öğe oluşturulur. Buna "widget değişikliği" denir ve tür değiştirirken durum kaybının nedenidir.

Aşama 4: Monte Etmeme (unmount)

Widget Widget Tree'den kaldırıldığında, öğenin unmount yöntemi çağrılır. Öğe Element Tree'den kaldırılır, RenderObject RenderObject Tree'den kaldırılır ve StatefulWidget için State nesnesinin dispose yöntemi çağrılır. Monte etmeme sonrasında, widget aynı konumda tekrar görünürse öğe yeniden kullanılabilir.

Element Tree'de Anahtarların Rolü

Anahtarlar (Key), Flutter'ın eski ve yeni Widget Tree'deki widget'ları konuma göre değil, benzersiz bir tanımlayıcıya göre eşleştirmesini sağlayan bir öğe tanımlama mekanizmasıdır. Anahtarlar, öğelerin sırasının değişebileceği dinamik listelerle (öğe ekleme, kaldırma veya yeniden düzenleme) çalışırken kritik öneme sahiptir.

Anahtarlar Element Tree'yi Nasıl Etkiler

Anahtar olmadan, Flutter öğeleri ağaçtaki konumlarına göre eşleştirir: eski ağaçtaki 0 konumundaki öğe, yeni ağaçtaki 0 konumundaki widget ile değiştirilir. Sıra değişmişse, öğeler karışır ve durum kaybolabilir veya yanlış verilere bağlanabilir. Bir anahtar, Flutter'ı konum yerine tanımlayıcıya göre öğe aramaya zorlar.

ValueKey, ObjectKey ve UniqueKey

ValueKey, bir öğeyi tanımlamak için basit bir değer (dize, sayı) kullanır. ObjectKey bir nesne referansı kullanır — öğenin kararlı bir dize tanımlayıcısı olmadığında uygundur. UniqueKey her oluşturmada benzersiz bir tanımlayıcı üretir — her widget örneği benzersiz olması gerektiğinde kullanılır.

dart
Column(
  children: items.map((item) => TodoItem(
    key: ValueKey(item.id),
    title: item.title,
    isDone: item.isDone,
  )).toList(),
)

Bu örnekte, item.id ile ValueKey, listedeki öğelerin sırası değiştiğinde her TodoItem'ın durumunu (örneğin, giriş alanı odağı) korumasını sağlar. Anahtar olmadan, ilk konumdaki öğe, aynı konumdaki önceki öğenin durumunu alırdı.

Element Tree Durumu Nasıl Yönetir

Flutter'da durum (State) widget'larda değil, öğelerde saklanır. Bir StatefulWidget yeniden oluşturulduğunda ve yeni bir widget örneği oluşturduğunda, ilgili StatefulElement eski State nesnesine bir referans tutar. Yeni widget, mevcut State'e bağlanarak verilerin yeniden yapılandırmalar arasında korunmasını sağlar.

Yeniden Yapılandırmada Durum Neden Kaybolmaz

Bir widget yeniden yapılandırılırken, Flutter yeni bir StatefulWidget örneği oluşturur, ancak ilgili StatefulElement Element Tree'de kalır. Öğe, State üzerinde update yöntemini çağırarak yeni widget'ı iletir. Böylece State nesnesi ve verileri korunur. Durum kaybı yalnızca widget türü değiştiğinde, anahtar değiştiğinde veya öğe ağaçtan kaldırıldığında meydana gelir.

InheritedWidget ve Element Tree

InheritedElement, alt öğelerin kurucular aracılığıyla açıkça iletme olmadan bir üst InheritedWidget'tan veri almasını sağlayan özel bir öğedir. InheritedWidget değiştiğinde, InheritedElement tüm bağımlı öğeleri bildirir ve bunlar yeniden oluşturulur. Bu mekanizma Theme, MediaQuery ve Provider'ın temelini oluşturur.

  • Bağımlılık — bir öğe, dependOnInheritedWidgetOfExactType'ı çağırdığında InheritedElement'e bağımlı olarak kaydolur.
  • Bildirim — InheritedWidget değiştiğinde, çerçeve tüm bağımlı öğeleri yeniden yapılandırma gerekiyor olarak işaretler.
  • Yeniden Yapılandırma — bağımlı öğeler bir sonraki karede yeniden oluşturulur ve yeni verilere göre kullanıcı arayüzünü günceller.

Element Tree'nin Performansa Etkisi

Element Tree bellek tüketir ve ilk render hızını etkiler. Her öğe belirli bir miktar bellek kaplar: widget'a referans, üst öğeye referans, alt öğeler listesi, bir yuva ve RenderObjectElement için ek alanlar. Element Tree'yi optimize etmek, başlangıç süresini kısaltır ve bellek tüketimini azaltır.

Öğelerin Yeniden Kullanımı

Flutter, yeniden yapılandırma sırasında öğeleri yeniden kullanmaya çalışır. Yeni yapılandırmadaki widget aynı tür ve anahtara sahipse, öğe yeniden oluşturulmaz — güncellenir. Bu, yeni bir öğe oluşturup ardından monte etmekten önemli ölçüde daha hızlıdır. Ancak, tür veya anahtar değiştiğinde, eski öğe monte edilmez ve sıfırdan yeni bir öğe oluşturulur.

RepaintBoundary ve Element Tree

RepaintBoundary, RenderObject Tree'de ağacın bir bölümünü izole eden ayrı bir RenderRepaintBoundary oluşturur. Element Tree düzeyinde, RepaintBoundary özel bir öğe oluşturmaz — SingleChildRenderObjectElement kullanır. Fark, RenderObject düzeyinde ortaya çıkar: RepaintBoundary içeriği değiştiğinde, yalnızca izole edilmiş alan yeniden boyanır.

İşlemRepaintBoundary YokRepaintBoundary Var
Yeniden BoyamaTüm ekranYalnızca izole alan
Süre60 FPS'de ~16 ms~2-5 ms
BellekMinimum+ katman başına birkaç KB

Tabloda görüldüğü gibi, RepaintBoundary değişen alanı izole ederek yeniden boyama süresini önemli ölçüde azaltır. Element Tree düzeyinde, bu ek yapılandırma gerektirmez — değişken widget'ı RepaintBoundary içine sarmak yeterlidir.

Sıkça Sorulan Sorular

Widget Tree ve Element Tree arasındaki fark nedir?

Widget Tree, her yeniden yapılandırmada yeniden oluşturulan bir yapılandırmadır. Element Tree, güncellemeler arasında kalan ve durumu, RenderObject'u ve widget yaşam döngüsünü yöneten kalıcı bir yapıdır.

Element Tree performans için neden önemlidir?

Element Tree olmadan, Flutter her durum değişikliğinde RenderObject Tree'yi yeniden oluşturmak zorunda kalırdı, bu da önemli gecikmelere neden olurdu. Element Tree, RenderObject ve State'i koruyarak yalnızca minimum değişikliklerin uygulanmasına izin verir.

Bir öğe Element Tree'den ne zaman kaldırılır?

Bir öğe, ilgili widget Widget Tree'den kaybolduğunda veya widget türü değiştiğinde (örneğin, Column'ın Row ile değiştirilmesi) veya anahtar değiştiğinde kaldırılır. Monte etmeme sırasında State üzerinde dispose çağrılır.

Anahtarlar Element Tree'yi nasıl etkiler?

Anahtarlar eşleştirme algoritmasını değiştirir: Flutter konuma göre öğe aramak yerine anahtar değerine göre öğe arar. Bu, widget'ların sırası veya miktarı değiştiğinde durumun korunmasını sağlar.

Element Tree'ye doğrudan erişilebilir mi?

Evet, BuildContext aracılığıyla, bir öğenin soyutlamasıdır. findAncestorWidgetOfExactType ve dependOnInheritedWidgetOfExactType yöntemleri, öğe ağacında yukarı doğru ilerleyerek Element Tree ile çalışır.

Özet

  • Element Tree — Widget ve RenderObject ağaçları arasında yeniden yapılandırmalar arasında durumu koruyan kalıcı bir ara katmandır.
  • Her widget bir öğe oluşturur: StatelessElement, StatefulElement veya RenderObjectElement (widget türüne bağlı olarak).
  • Yaşam döngüsü oluşturma, monte etme, güncelleme ve monte etmeme adımlarını içerir — bu aşamaları anlamak hata ayıklama için gereklidir.
  • Anahtarlar (Key) Element Tree düzeyinde çalışarak dinamik değişiklikler sırasında doğru widget eşleştirmesini sağlar.
  • StatefulElement, tür ve anahtar değişmezse widget yeniden yapılandırması sırasında korunan bir State nesnesi saklar.
  • InheritedElement, bağımlı öğelere değişiklikleri bildirerek ağaçta aşağı doğru reaktif veri iletimini sağlar.
  • Üç katmanlı mimari Widget → Element → RenderObject, Flutter'ın kullanıcı arayüzünü verimli bir şekilde güncellemesine ve pahalı render işlemlerini en aza indirmesine olanak tanır.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun