Kullanicilarin yuzde 53'u, 3 saniyeden fazla yuklenen bir uygulamayi terk ediyor. Flutter ile 60fps akiciliginda uygulamalar gelistirmek mumkun ama otomatik degil. Yanlis widget yapilari, gereksiz rebuild'ler ve optimize edilmemis gorseller, uygulamanizi yavaslatabilir.
Bu rehberde Flutter performansini etkileyen tum faktorleri inceleyecek ve her biri icin somut cozumler sunacagiz. DevTools ile profiling'den Impeller rendering engine'ine, bellek yonetiminden network optimizasyonuna kadar her konuyu ele alacagiz.
Not: Performans olcumleri her zaman release mode veya profile mode ile yapilmalidir. Debug mode optimizer devre disidir ve yaniltici sonuclar verir.
Icindekiler
- Flutter Rendering Pipeline
- Widget Rebuild Optimizasyonu
- const Constructor Gucu
- ListView ve Grid Optimizasyonu
- Gorsel Optimizasyonu
- Impeller Rendering Engine
- DevTools ile Profiling
- Bellek Yonetimi
- Network Optimizasyonu
- Build Boyutu Kucultme
- Best Practices Checklist
- Sonuc ve Oneriler
1. Flutter Rendering Pipeline
Flutter'in rendering sureci 3 asamadan olusur:
Pipeline Asamalari
Asama | Gorev | Darbogazda Ne Olur |
|---|---|---|
**Build** | Widget tree olusturma | Asiliri rebuild, karmasik tree |
**Layout** | Boyut ve konum hesaplama | Ic ice Intrinsic*, cok fazla constraint |
**Paint** | Piksellere cizim | Agir clip, shader, opacity |
Flutter her frame'de bu 3 asamayi 16ms icinde tamamlamalidir (60fps icin). Herhangi bir asamada gecikme olursa "jank" (takilma) yasanir.
dart
1// Rendering pipeline'i gorsellestirme2// DevTools > Performance > Frame chart ile izleyebilirsiniz3 4// Build asamasi - Widget tree'yi etkili tutun5// KOTU: Gereksiz derinlik6Widget build(BuildContext context) {7 return Container(8 child: Padding(9 padding: const EdgeInsets.all(16),10 child: Center(11 child: Column(12 children: [13 Container(14 decoration: BoxDecoration(color: Colors.blue),15 child: Padding(16 padding: const EdgeInsets.all(8),17 child: Text('Merhaba'),18 ),19 ),20 ],21 ),22 ),23 ),24 );25}26 27// IYI: Duz ve temiz28Widget build(BuildContext context) {29 return Padding(30 padding: const EdgeInsets.all(16),31 child: Center(32 child: Container(33 padding: const EdgeInsets.all(8),34 decoration: BoxDecoration(color: Colors.blue),35 child: const Text('Merhaba'),36 ),37 ),38 );39}2. Widget Rebuild Optimizasyonu
Widget rebuild, Flutter performansinin en kritik noktasidir:
dart
1// KOTU: Parent rebuild olunca tum children da rebuild olur2class BadExample extends StatefulWidget {3 const BadExample({super.key});4 5 @override6 State createState() => _BadExampleState(); 7}8 9class _BadExampleState extends State { 10 int _counter = 0;11 12 @override13 Widget build(BuildContext context) {14 return Column(15 children: [16 Text('Sayi: $_counter'),17 // Bu widget _counter ile ilgisi yok ama her seferinde rebuild olur!18 HeavyChartWidget(data: staticData),19 ElevatedButton(20 onPressed: () => setState(() => _counter++),21 child: const Text('Artir'),22 ),23 ],24 );25 }26}27 28// IYI: Sadece degisen kismi rebuild et29class GoodExample extends StatefulWidget {30 const GoodExample({super.key});31 32 @override33 State createState() => _GoodExampleState(); 34}35 36class _GoodExampleState extends State { 37 int _counter = 0;38 39 @override40 Widget build(BuildContext context) {41 return Column(42 children: [43 // ValueListenableBuilder sadece counter degistiginde rebuild olur44 Text('Sayi: $_counter'),45 // const ile isaretlenmis widget ASLA rebuild olmaz46 const HeavyChartWidget(data: staticData),47 ElevatedButton(48 onPressed: () => setState(() => _counter++),49 child: const Text('Artir'),50 ),51 ],52 );53 }54}Rebuild Izleme Teknikleri
DevTools'un "Widget rebuild stats" ozelligini acarak hangi widget'larin ne siklikla rebuild edildigini gorebilirsiniz. Bu, performans sorunlarini tespit etmenin en kolay yoludur.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
3. const Constructor Gucu
const keyword'u Flutter'da performansin anahtaridir:
dart
1// const widget COMPILE-TIME'da olusturulur2// Runtime'da tekrar olusturulmaz, rebuild edilmez!3 4// KOTU: Her build'de yeni instance5class MyWidget extends StatelessWidget {6 @override7 Widget build(BuildContext context) {8 return Padding(9 padding: EdgeInsets.all(16), // Her seferinde yeni EdgeInsets10 child: Text(11 'Sabit Metin',12 style: TextStyle(fontSize: 16), // Her seferinde yeni TextStyle13 ),14 );15 }16}17 18// IYI: const ile tek instance19class MyWidget extends StatelessWidget {20 const MyWidget({super.key});21 22 @override23 Widget build(BuildContext context) {24 return const Padding(25 padding: EdgeInsets.all(16), // Compile-time'da olusturulur26 child: Text(27 'Sabit Metin',28 style: TextStyle(fontSize: 16), // Compile-time'da olusturulur29 ),30 );31 }32}const Kullanim Kurallari
Durum | const Kullanilabilir mi? | Aciklama |
|---|---|---|
Sabit metin | Evet | const Text('Merhaba') |
Sabit renk | Evet | const Color(0xFF000000) |
Degisken deger | Hayir | Text(userName) |
Sabit liste | Evet | const [1, 2, 3] |
final degisken | Hayir | final yerine const kullanin |
4. ListView ve Grid Optimizasyonu
Buyuk listeler Flutter'in en hassas performans noktasidir:
dart
1// KOTU: Tum ogeler bir anda olusturulur (100+ item'da facia)2ListView(3 children: items.map((item) => ItemWidget(item: item)).toList(),4);5 6// IYI: Sadece gorunen ogeler olusturulur (lazy loading)7ListView.builder(8 itemCount: items.length,9 itemBuilder: (context, index) {10 return ItemWidget(item: items[index]);11 },12);13 14// DAHA IYI: itemExtent ile scroll performansini artirin15ListView.builder(16 itemCount: items.length,17 itemExtent: 72.0, // Sabit yukseklik18 itemBuilder: (context, index) {19 return ItemWidget(item: items[index]);20 },21);22 23// EN IYI: Karmasik ogeler icin AutomaticKeepAlive ve RepaintBoundary24ListView.builder(25 itemCount: items.length,26 itemExtent: 72.0,27 addAutomaticKeepAlives: true,28 addRepaintBoundaries: true,29 itemBuilder: (context, index) {30 return ItemWidget(31 key: ValueKey(items[index].id),32 item: items[index],33 );34 },35);5. Gorsel Optimizasyonu
dart
1// Gorsel boyutunu sinirla2Image.network(3 imageUrl,4 cacheWidth: 300, // Decode edilecek genislik5 cacheHeight: 300, // Decode edilecek yukseklik6 fit: BoxFit.cover,7);8 9// cached_network_image paketi ile onbellekleme10CachedNetworkImage(11 imageUrl: imageUrl,12 width: 300,13 height: 300,14 memCacheWidth: 300,15 fit: BoxFit.cover,16 placeholder: (context, url) => const ShimmerPlaceholder(),17 errorWidget: (context, url, error) => const Icon(Icons.error),18);6. Impeller Rendering Engine
Impeller, Flutter'in yeni rendering engine'idir ve Skia'nin yerini alir:
Ozellik | Skia | Impeller |
|---|---|---|
**Shader Compilation** | Runtime (jank yaratir) | Build-time (jank yok) |
**Ilk Frame** | Yavas (shader warmup) | Hizli |
**Metal Destegi** | Dolayli | Dogrudan |
**Vulkan Destegi** | Dolayli | Dogrudan |
**iOS Varsayilan** | Hayir (Flutter 3.16+) | Evet |
**Android Varsayilan** | Evet (gecis suruyor) | Hayir (opt-in) |
dart
1// Impeller'i Android'de aktif etmek icin:2// android/app/src/main/AndroidManifest.xml3// 4// android:name="io.flutter.embedding.android.EnableImpeller"5// android:value="true" />6 7// Performans farkini olcmek icin profile mode'da test edin:8// flutter run --profile --trace-skia (Skia)9// flutter run --profile --enable-impeller (Impeller)7. DevTools ile Profiling
bash
1# DevTools'u profile modunda calistirin2flutter run --profile3 4# DevTools'u acin5flutter pub global activate devtools6dart devtoolsDevTools Sekmeleri
Sekme | Amac | Ne Zaman Kullanilir |
|---|---|---|
**Performance** | Frame timing | Jank, yavas animasyon |
**CPU Profiler** | Fonksiyon sureleri | Yavas islem tespiti |
**Memory** | Bellek kullanimi | Memory leak, yuksek RAM |
**Network** | HTTP trafigi | Yavas API, fazla istek |
**Widget Inspector** | Widget tree | Gereksiz rebuild tespiti |
8. Bellek Yonetimi
dart
1// Gorsel onbellegi yonetimi2class ImageCacheManager {3 static void configureCacheSize() {4 // Onbellek boyutunu sinirla5 PaintingBinding.instance.imageCache.maximumSize = 100; // maks 100 gorsel6 PaintingBinding.instance.imageCache.maximumSizeBytes = 50 * 1024 * 1024; // 50MB7 }8 9 static void clearCache() {10 PaintingBinding.instance.imageCache.clear();11 PaintingBinding.instance.imageCache.clearLiveImages();12 }13}14 15// Stream subscription temizligi16class MyWidget extends StatefulWidget {17 const MyWidget({super.key});18 19 @override20 State createState() => _MyWidgetState(); 21}22 23class _MyWidgetState extends State { 24 late final StreamSubscription _subscription;25 26 @override27 void initState() {28 super.initState();29 _subscription = someStream.listen((data) {30 // data isle31 });32 }33 34 @override35 void dispose() {36 _subscription.cancel(); // KRITIK: Temizlemeyi unutma!37 super.dispose();38 }39 40 @override41 Widget build(BuildContext context) {42 return const SizedBox();43 }44}9. Network Optimizasyonu
dart
1// HTTP isteklerini optimize etme2class OptimizedApiClient {3 final Dio _dio;4 5 OptimizedApiClient() : _dio = Dio(BaseOptions(6 connectTimeout: const Duration(seconds: 10),7 receiveTimeout: const Duration(seconds: 15),8 sendTimeout: const Duration(seconds: 10),9 )) {10 // Interceptor ile request/response loglama11 _dio.interceptors.add(LogInterceptor(12 requestBody: true,13 responseBody: true,14 ));15 16 // Cache interceptor17 _dio.interceptors.add(DioCacheInterceptor(18 options: CacheOptions(19 store: MemCacheStore(),20 maxStale: const Duration(minutes: 5),21 ),22 ));23 }24 25 // Paralel istekler26 Future> fetchParallel(List urls) async {
27 final futures = urls.map((url) => _dio.get(url));28 final responses = await Future.wait(futures);29 return responses.map((r) => r.data).toList();30 }31}10. Build Boyutu Kucultme
bash
1# APK boyutunu analiz et2flutter build apk --analyze-size3 4# App bundle (daha kucuk)5flutter build appbundle6 7# Obfuscation ile boyutu azalt8flutter build apk --obfuscate --split-debug-info=build/debug-info9 10# Kullanilmayan kaynaklari tespit et11flutter pub run dart_code_metrics:metrics analyze libBoyut Azaltma Teknikleri
Teknik | Kazanc | Zorluk |
|---|---|---|
**App Bundle** (AAB) | %20-30 | Kolay |
**Obfuscation** | %5-10 | Kolay |
**Tree Shaking** | Otomatik | Yok |
**Deferred Components** | %10-40 | Zor |
**SVG yerine Icon Font** | %5-15 | Kolay |
**WebP gorsel formati** | %25-35 | Kolay |
11. Best Practices Checklist
- const constructor kullan (mumkun olan her yerde)
- ListView.builder kullan (ListView degil)
- itemExtent belirt (sabit yukseklik varsa)
- RepaintBoundary ekle (agir widget'lara)
- Gorselleri cacheWidth/cacheHeight ile sinirla
- Profile mode ile test et (debug mode degil)
- DevTools Performance sekmesini kullan
- Stream subscription'lari dispose et
- Impeller'i etkinlestir (iOS varsayilan, Android opt-in)
- App Bundle kullan (APK yerine)
Sonuc ve Oneriler
Flutter performans optimizasyonu, dogru araclari ve teknikleri bildiginde aslinda kolaydir. Anahtar, onceliklendirmektir — once olcun, sonra optimize edin. Premature optimization, karmasiklik yaratir.
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Okuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var:

