RenderObject Tree Flutter hiyerarşisinin üçüncü seviyesidir ve arayüzün ekranda gerçekten oluşturulmasından sorumludur. Bu ağacın her düğümü, boyut hesaplama (layout) ve çizim (painting) yaparak widget yapılandırmasını piksellere dönüştürür. Widget Tree'nin aksine, RenderObject Tree bir kez oluşturulur ve yalnızca geometri veya görünüm değiştiğinde güncellenir. Flutter API Reference, 2025'e göre, RenderObject Tree'nin verimliliği, animasyonların akıcılığını ve uygulamanın yanıt verebilirliğini doğrudan belirler.
Anahtar noktalar
RenderObject Tree bellek arayüzün gerçek temsili olarak hizmet eden oluşturma nesnelerinin hiyerarşik bir yapısıdır. Her RenderObject kendi boyutunu, ekrandaki konumunu ve kendini nasıl çizeceğini bilir. Hafif olan ve saniyede yüzlerce kez yeniden oluşturulabilen widget'ların aksine, RenderObject grafik boru hattına doğrudan erişimi olan ağır bir nesnedir.
Widget'tan piksellere giden yol üç aşamadan geçer: Widget Tree ekranda ne olması gerektiğini açıklar; Element Tree yaşam döngüsünü yönetir; RenderObject Tree asıl işi yapar. Her RenderObjectWidget (Padding, Transform, CustomPaint gibi) oluşturma ağacına eklenen bir RenderObject oluşturur. RenderBox, standart widget'ların %99'unda kullanılan en yaygın RenderObject türüdür.
RenderObject layout ve paint için arayüzü tanımlayan soyut bir sınıftır. Üst RenderObject ve alt nesnelere referansların yanı sıra soyut yöntemleri içerir: performLayout, paint ve hitTest. Her somut RenderObject bu yöntemleri davranışına göre uygular: RenderFlex alt öğeler arasında boşluk dağıtır, RenderImage görüntü görüntüler, RenderParagraph metin oluşturur.
abstract class RenderObject {
RenderObject? parent;
Constraints constraints;
ParentData? parentData;
bool _needsLayout = true;
bool _needsPaint = true;
void performLayout();
void paint(PaintingContext context, Offset offset);
}
Bu basitleştirilmiş yapıda, RenderObject nesneyi güncelleme gerektiriyor olarak işaretleyen _needsLayout ve _needsPaint bayraklarını içerir. Widget Tree değiştiğinde, Element Tree ilgili RenderObject'leri layout veya paint için "kirli" olarak işaretler ve sonraki karede Flutter yalnızca gerekli işlemleri gerçekleştirir.
Her RenderObject iki ana aşama gerçekleştirir: layout (boyut ve konum belirleme) ve paint (çizim). Bu aşamalar katı bir sırayla yürütülür: önce tüm ağaç için layout, ardından paint. Layout değişmediyse paint aşaması atlanabilir, bu da GPU kaynaklarından tasarruf sağlar.
Layout sırasında Flutter, RenderObject Tree aracılığıyla yukarıdan aşağıya kısıtlamalar (constraints) iletir. Her üst öğe, alt öğesi için minimum ve maksimum genişlik ve yükseklik belirler. Alt öğe, bu kısıtlamalar dahilinde boyutunu hesaplar ve üst öğeye döndürür. Bu sürece "aşağı geçiş" (kısıtlamaları aşağı iletme) ve "yukarı geçiş" (boyutları yukarı iletme) denir.
Layout tamamlandıktan sonra Flutter paint işlemini gerçekleştirir — her RenderObject'ün çizimi. Üst öğe bir PaintingContext oluşturur, bunu alt nesnelere iletir ve ofseti (offset) belirtir. Her RenderObject grafik ilkellerini (dikdörtgenler, daireler, metin, görüntüler ve dönüşümler) kullanarak Canvas üzerinde kendini çizer. Canvas doğrudan Skia veya Impeller ile etkileşime girer.
Flutter, işi en aza indirmek için "kirli" düğüm mekanizması kullanır. Yalnızca bir RenderObject'ün boyutu değiştiğinde, Flutter tüm ağacın layout'unu yeniden hesaplamaz — değişen düğümü ve sabit boyutlu en yakın RenderBox'a kadar olası atalarını işaretler. Benzer şekilde, görünüm değiştiğinde, layout yeniden yapılmadan yalnızca paint işaretlenir.
Flutter farklı görevler için çeşitli RenderObject kategorileri sağlar: standart dikdörtgen öğeler için RenderBox, kaydırılabilir alanlar için RenderSliver ve CustomPainter aracılığıyla standart olmayan oluşturma için özel RenderObject'ler. Her tür, oluşturma ağacındaki rolü için optimize edilmiştir.
RenderBox dikdörtgen arayüz öğeleri için temel sınıftır. Alt türleri şunları içerir: RenderPadding (dolgu ekler), RenderTransform (dönüşümler uygular), RenderFlex (Row ve Column uygular), RenderStack (öğeleri üst üste koyar), RenderImage (görüntüleri gösterir), RenderParagraph (metin oluşturur). Her alt tür, kendi mantığı için performLayout ve paint'i geçersiz kılar.
RenderSliver kaydırılabilir alanlarla çalışmak için bir RenderObject türüdür. RenderBox'ın aksine, Sliver görüntü alanı (viewport) bilgisi içeren SliverConstraints kullanır. RenderSliverList ve RenderSliverGrid, yalnızca görünür alandaki öğeler için RenderObject'ler oluşturarak milyonlarca girişi olan listelerin işlenmesine olanak tanır.
Standart olmayan grafikler için CustomPaint ve CustomPainter kullanın. CustomPaint, CustomPainter'ın paint yöntemlerini çağıran RenderCustomPaint'i oluşturur. Bu, Canvas üzerinde tam kontrol ile isteğe bağlı şekiller, grafikler ve animasyonlar çizmeye olanak tanır. Flutter Ekibine göre CustomPainter, karmaşık vektör grafikleri için iç içe standart widget'lardan daha verimlidir.
class CirclePainter extends CustomPainter {
final Color color;
CirclePainter({required this.color});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = color;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
size.width / 3,
paint,
);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) =>
oldDelegate.color != color;
}
Bu örnekte, CirclePainter Canvas üzerinde bir daire çizer. shouldRepaint yöntemi yalnızca renk değiştiğinde true döndürerek gereksiz yeniden çizimleri önler. CustomPainter mümkün olduğunca hafif olmalıdır — tüm ağır hesaplamaları paint yöntemleri dışında gerçekleştirin.
RenderObject Tree RenderObjectWidget mekanizması aracılığıyla Element Tree'den oluşturulur. Her RenderObjectWidget (Padding, Transform, CustomPaint) bir RenderObjectElement oluşturur ve bu da karşılık gelen RenderObject'i oluşturur ve yönetir. Öğe bir aracı görevi görür: widget'tan RenderObject'e yapılandırmayı iletir ve RenderObject'i değişikliklerden haberdar eder.
Bir RenderObjectElement monte edildiğinde, widget'ında createRenderObject yöntemini çağırır. Widget bir RenderObject örneği oluşturur ve öğeye döndürür. Öğe, üst RenderObject üzerinde insertChildLayout yöntemini çağırarak RenderObject'i RenderObject Tree'ye ekler. Bu işlem yalnızca ilk montajda gerçekleşir — sonraki güncellemelerde öğe, mevcut RenderObject'in parametrelerini basitçe günceller.
Widget'ın yapılandırması değiştiğinde (örneğin, padding değeri değişir), öğe updateRenderObject yöntemini çağırır ve yeni yapılandırmayı mevcut RenderObject'e iletir. RenderObject kendini layout veya paint için "kirli" olarak işaretler ve sonraki karede çerçeve gerekli güncellemeleri gerçekleştirir.
Bir öğe kaldırıldığında, unmount yöntemi çağırılır ve RenderObject'i RenderObject Tree'den kaldırıp kaynakları serbest bırakır. Üst öğeden ayrılmak için RenderObject.remove çağrılır ve ardından nesne çöp toplayıcı tarafından toplanabilir. Flutter, karşılık gelen bir öğe olmadan hiçbir RenderObject'un ağaçta asılı kalmamasını garanti eder.
RepaintBoundary içeriğini oluşturmak için ayrı bir katman oluşturan bir widget'tır. Bir RepaintBoundary içindeki içerik değiştiğinde, yalnızca bu katman yeniden boyanır, ekranın geri kalanı değişmeden kalır. RepaintBoundary özellikle animasyonlar, video oynatıcılar, etkileşimli grafikler ve sık güncellenen diğer öğeler için kullanışlıdır.
RepaintBoundary'in özünde RenderRepaintBoundary bulunur — ayrı bir PictureLayer oluşturan özel bir RenderObject. İlk oluşturmada, RenderRepaintBoundary grafik komutlarını bu katmana kaydeder. Sonraki güncellemelerde, yalnızca RepaintBoundary içindeki içerik değişirse, Flutter tüm ekran yerine yalnızca bu katmanı yeniden boyar. Diğer katmanlar değişmeden kalır ve yeniden kullanılır.
Her widget'ın RepaintBoundary'e ihtiyacı yoktur. Arayüzün bir kısmı yüksek frekansta (60 FPS veya üzeri) güncellenirken ekranın geri kalanı statik olduğunda kullanın. Tipik örnekler: animasyonlu yükleme göstergesi, video oynatıcı, oyun Canvas'ı, sık yeniden çizim yapan CustomPainter. Statik metin veya düğmeler için RepaintBoundary gereksizdir ve yalnızca bellek tüketimini artırır.
| Senaryo | Öneri | Neden |
|---|---|---|
| Animasyon | RepaintBoundary ile sarma | Sık güncellenen alanı izole eder |
| Kaydırılabilir liste | Gerekli değil | ListView otomatik olarak katman kullanır |
| Statik metin | Gerekli değil | Sık yeniden çizim yok |
| CustomPainter | Önerilir | Sık grafik yeniden çizimi |
Performans RenderObject Tree'nin düğüm sayısına, ağacın derinliğine ve yeniden oluşturma sıklığına bağlıdır. Flutter DevTools ("Rendering" sekmesi), RenderObject Tree'yi gerçek zamanlı olarak analiz etmenizi sağlar: yeniden çizim sayısı, layout ve paint süresi, katman sayısı ve boyutları. Düzenli analiz, darboğazları belirlemeye yardımcı olur.
Overdraw tek bir pikselin kare başına birden çok kez çizildiği bir durumdur. Örneğin, yarı saydam bir widget başka bir widget ile örtüştüğünde, GPU her iki katmanı da çizer. Saydam olmayan öğeler için opak bayraklar (decoration yerine color ile Container) kullanın, böylece Flutter görünmeyen katmanları atlayabilir. Flutter Ekibine göre, overdraw'ı azaltmak paint süresini %30'a kadar düşürebilir.
Her RepaintBoundary ve bazı widget'lar (Opacity, ClipRRect, Transform) ayrı bir katman (PictureLayer) oluşturur. Çok fazla katman birleştirme süresini artırır. Gruplama kullanın: tek tek öğelerde birden çok Opacity widget'ı yerine kapsayıcıya tek bir Opacity uygulayın. Her öğede ClipRRect yerine ortak kapsayıcıda ClipRRect kullanın.
Bir widget const olarak bildirildiğinde, Flutter yapılandırmasının değişmeyeceğini bilir ve ilgili RenderObject'i yeniden oluşturmadan yeniden kullanabilir. const yapıcıları çöp toplayıcı yükünü azaltır ve ilk kareyi hızlandırır. Sabit parametrelere sahip widget'lar için const kullanın: simgeler, başlıklar, dekoratif öğeler.
const Text("Başlık", style: TextStyle(fontSize: 24));
const Icon(Icons.home, color: Colors.blue);
const SizedBox.shrink();
Sıkça Sorulan Sorular
Widget Tree her yeniden oluşturmada yeniden oluşturulan hafif bir arayüz yapılandırmasıdır. RenderObject Tree ise kalıcı olan ve yalnızca geometri veya görünüm değiştiğinde güncellenen ağır bir oluşturma nesnesi ağacıdır.
Flutter DevTools kullanın — "Rendering" sekmesi. Oluşturma katmanlarını, layout ve paint sürelerini ve her RenderObject hakkında ayrıntılı bilgileri (boyutlar, kısıtlamalar, kirli bayraklar) göreceksiniz.
Dirty güncelleme gerektiriyor olarak işaretlenmiş bir RenderObject'tur. Yapılandırma değiştiğinde _needsLayout veya _needsPaint bayrağı ayarlanır ve Flutter sonraki karede bu düğüm için layout veya paint gerçekleştirir.
Evet, RenderBox alt sınıfı oluşturun ve performLayout ile paint yöntemlerini geçersiz kılın. Özel RenderObject'i Widget Tree'ye yerleştirmek için RenderObjectWidget kullanın. Bu, standart olmayan oluşturma için gelişmiş bir tekniktir.
RepaintBoundary RenderRepaintBoundary oluşturur ve RenderObject Tree'nin bir kısmını ayrı bir katmanda izole eder. İçerik değiştiğinde, yalnızca bu katman yeniden boyanır ve ağacın geri kalanı değişmeden kalır.
Özet
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.
Ayrıca okuyun