Bu rehber, Flutter mobil uygulama geliştirme esnasında gizli rebuild'leri ölçme ve azaltma üzerine pratik adımlar sunar; DevTools, widget profiler, Provider/Selector ve mikro-optimizasyonlar ile somut iyileştirmeler gösterir.
Flutter state management rebuild'leri: Build maliyeti ölçme ve azaltma
Neden build maliyeti önemlidir - Flutter mobil uygulama geliştirme baglaminda
Bir frame icindeki build islemleri CPU kullanimini direkt etkiler; DevTools uzerinden toplanan widget rebuild sayisi ve frame build time istatistikleri uygulamanin jank ve input gecikmesine nasil yansıdığını verir. Hemen deneyin: uygulamayi profiling modunda calistirin:
flutter run --profile ve DevTools > Performance > Timeline kaydını baslatın; kayıttan frame bazlı "Build" suresini export ederek ortalama hesaplayabilirsiniz (baseline).DevTools ile rebuild tespiti ve timeline analizi
Somut adımlar: 1) Uygulamayı cihazda baglayip profile modda calistirin:
flutter run --profile --observatory-port=0 2) Tarayıcıda dart devtools acın: dart pub global activate devtools
dart devtools 3) DevTools Performance > Record timeline ile senaryoyu tekrar edin, sonra 'Frame' uzerinden Build ve Rasterizer zamanlarini inceleyin. Bu adımda "Rebuild Count" ve "Build Time" kolonlarını csv'ye export ederek before-after karsilastirmaya hazir veri elde edebilirsiniz.Analiz icin pratik: exported CSV'den Python veya jq ile ortalama hesaplayın. Ornegin Linux/Mac terminalinde:
awk -F, '{sum+=$3; n++} END {print "avg", sum/n}' timeline.csv (burada 3. kolon build time yaptığınız export yapılandırmasına gore değişebilir). Bu sayede, optimizasyon once/sonra karsilastirmalari sayısal hale gelir.Yaygın anti-pattern: Provider/InheritedWidget ile istemsiz rebuild'ler
Problem ornegi: ListView icerisindeki item widget'larin tumunun, parent Provider'da degisiklikten sonra yeniden cizilmesi. Yanlis kullanim:
// yanlis: tum itemler bu sekilde dinliyor
Widget build(BuildContext context) {
final store = Provider.of(context); // listen: true default
return ListView.builder(
itemCount: store.items.length,
itemBuilder: (_, i) => ItemWidget(item: store.items[i]),
);
}
Bu durumda her store guncellemesinde tum itemler yeniden build olur; bunu tespit etmek icin DevTools'ta rebuild count'u izlemeniz gerekir (Performance > Refresh widget rebuild info).Duzeltme: dinleme kisimini daraltin veya Selector/Consumer kullanin. Ornek cozum:
// dogru: sadece gereken kisim dinlenir
Widget build(BuildContext context) {
return ListView.builder(
itemCount: context.read().items.length, // listen yok
itemBuilder: (_, i) => Selector(
selector: (_, s) => s.items[i],
builder: (_, item, __) => ItemWidget(item: item),
),
);
}
Bu degisiklikten once-sonra karsilastirmak icin DevTools'ta ayni senaryoyu kaydedip "Build" surelerinin ve rebuild sayisinin dustugunu gosteren CSV'leri karsilastirin.Instrumentasyon: BuildCounter ve zaman olcumu ile sorun diger boyutlariyla gorunur
Kendi instrumentasyonunuzu eklemek buyuk fayda verir; asagida, her build cagrisinda sayan ve build surelerini loglayan minimal bir wrapper var. Bu widget'i ilgili subtree'e koyarak hangi alt-kodun ne kadar sure harcadigini sayisallaştırabilirsiniz. Kodu proje icerisine ekleyin ve profile modda calistirin:
class BuildProfiler extends StatefulWidget {
final Widget child;
final String tag;
BuildProfiler({required this.child, required this.tag});
@override
_BuildProfilerState createState() => _BuildProfilerState();
}
class _BuildProfilerState extends State {
int builds = 0;
@override
Widget build(BuildContext context) {
final sw = Stopwatch()..start();
final w = widget.child;
sw.stop();
builds++;
// console log, veya metrics exporter (Prometheus/StatsD) kullanın
debugPrint('${widget.tag} build #$builds time=${sw.elapsedMicroseconds}us');
return w;
}
}
Bu tip instrumentasyon, DevTools rebuild sayısı ile beraber kullanıldığında hatanın lokalize edilmesini kolaylaştırır.Düzeltme stratejileri, mikro-optimizasyonlar ve karşılaştırma metrikleri
Somut öneri 1 - Ağır işlemleri build dışına taşıyın: UI oluşturmadan önceki hesaplamalar için initState veya memoization kullanın. Örnek:
// yanlış: her build anında tekrar hesaplama
Widget build(BuildContext ctx) {
final heavy = expensiveComputation();
return Text('$heavy');
}
// doğru: tek seferlik hesapla
late final heavyValue = expensiveComputation();
void initState() {
super.initState();
heavyValue = expensiveComputation();
}
Önce/sonra karşılaştırma için DevTools timeline exportunu kullanın; ortalama build zamanını ve rebuild sayısını kaydedin ve yüzde değişim hesaplayın.Somut öneri 2 - State derinliğini daraltın: global state değişiklikleri tüm subtree'leri tetikler. Provider/riverpod kullanıyorsanız, Selector veya ref.watch seviyesini değiştirerek sadece gerekli diğer widget'ları tetikleyin. Örnek küçük değişiklik:
// provider selector örneği
Selector(
selector: (_, s) => s.counter,
builder: (_, counter, __) => Text('$counter'),
);
Somut öneri 3 - Const ve child caching: Stateless widget'lar için const kullanımı ve Scrollable item caching (ListView.builder + itemExtent veya cacheExtent) rebuild maliyetini azaltır. Örnek komut:
ListView.builder(itemExtent: 72.0, cacheExtent: 1024.0, ...)Karşılaştırma metrikleri: optimizasyon öncesi ve sonrası için aşağıdaki metrikleri toplayın: ortalama Build Time (ms), rebuild count per frame, 90. persentil frame render süresi. Bu sayıları DevTools'tan export edip Python ile karşılaştırın:
python -c "import csv,sys; r=list(csv.reader(open('before.csv'))); print('avg', sum(map(float,[r[i][2] for i in range(1,len(r))]))/(len(r)-1))" Bu yaklaşım, optimizasyonun etkisini sayısal olarak ispatlamanıza yardımcı olur.İlgili Eğitim
Sık Sorulan Sorular
flutter state management kullanırken tüm widgetlar neden yeniden build oluyor ve nasıl tespit ederim?
Tüm widget'ların yeniden build olma nedeni genellikle state'in yüksek seviyede değiştirilmesi veya Provider/InheritedWidget'in geniş kapsamlı dinlenmesi. Tespit için: uygulamayı flutter run --profile ile çalıştırın, DevTools Performance'ta Timeline kaydını alıp 'Rebuild' sayısını ve her frame içindeki 'Build' sürelerini inceleyin. Ek olarak BuildProfiler wrapper (yukarıdaki kod) ile subtree seviyesinde build sayısı ve sürelerini loglayın.
flutter mobil uygulama geliştirme projemde Provider yerine Selector/Consumer kullanmamın somut faydası nedir?
Selector/Consumer ile sadece ihtiyac duyulan alan dinlenir; bu sayede parent state degissede diger subtree'ler yeniden build olmaz. Onemli adim: Provider.of(context) kullanirken default listen:true oldugunu unutmayin; eger sadece okuma yapacaksaniz context.read kullanin. Before-after olcumu icin DevTools'tan rebuild count ve frame build time verilerini export edin.
dart programlama eğitimi veya flutter kursu alan geliştiriciler icin hangi profiling aracini onerirsiniz?
Deneyimli yetenekler icin ilk tercih Dart DevTools olmalidir: widget rebuild profiler, CPU profiling (sample ve instrumentation), memory snapshot ve timeline hepsi bir arada. Ek olarak Android/adb tarafli trace gerekiyorsa perfetto ile sistem seviyesinde iz alip DevTools ile korrele edebilirsiniz. Komut ornegi:
flutter run --profile --trace-skia ve sonra DevTools ile kaydi analiz edin.AI / LLM Discovery
Bu makale Opendart Akademi Flutter eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.



