Tüm Yazılar
KategoriFlutter
Okuma Süresi
23 dk okuma
Yayın Tarihi
...
Kelime Sayısı
1.769kelime

Kahveni hazırla - bu içerikli bir makale!

Flutter uygulamalarinda performans optimizasyonu. Widget rebuild, Impeller, DevTools profiling, bellek yonetimi ve render optimizasyonu teknikleri.

Flutter Performans Optimizasyonu: 60fps Garanti Rehberi

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


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 gorsellestirme
2// DevTools > Performance > Frame chart ile izleyebilirsiniz
3 
4// Build asamasi - Widget tree'yi etkili tutun
5// KOTU: Gereksiz derinlik
6Widget 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 temiz
28Widget 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 olur
2class BadExample extends StatefulWidget {
3 const BadExample({super.key});
4 
5 @override
6 State createState() => _BadExampleState();
7}
8 
9class _BadExampleState extends State {
10 int _counter = 0;
11 
12 @override
13 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 et
29class GoodExample extends StatefulWidget {
30 const GoodExample({super.key});
31 
32 @override
33 State createState() => _GoodExampleState();
34}
35 
36class _GoodExampleState extends State {
37 int _counter = 0;
38 
39 @override
40 Widget build(BuildContext context) {
41 return Column(
42 children: [
43 // ValueListenableBuilder sadece counter degistiginde rebuild olur
44 Text('Sayi: $_counter'),
45 // const ile isaretlenmis widget ASLA rebuild olmaz
46 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 olusturulur
2// Runtime'da tekrar olusturulmaz, rebuild edilmez!
3 
4// KOTU: Her build'de yeni instance
5class MyWidget extends StatelessWidget {
6 @override
7 Widget build(BuildContext context) {
8 return Padding(
9 padding: EdgeInsets.all(16), // Her seferinde yeni EdgeInsets
10 child: Text(
11 'Sabit Metin',
12 style: TextStyle(fontSize: 16), // Her seferinde yeni TextStyle
13 ),
14 );
15 }
16}
17 
18// IYI: const ile tek instance
19class MyWidget extends StatelessWidget {
20 const MyWidget({super.key});
21 
22 @override
23 Widget build(BuildContext context) {
24 return const Padding(
25 padding: EdgeInsets.all(16), // Compile-time'da olusturulur
26 child: Text(
27 'Sabit Metin',
28 style: TextStyle(fontSize: 16), // Compile-time'da olusturulur
29 ),
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 artirin
15ListView.builder(
16 itemCount: items.length,
17 itemExtent: 72.0, // Sabit yukseklik
18 itemBuilder: (context, index) {
19 return ItemWidget(item: items[index]);
20 },
21);
22 
23// EN IYI: Karmasik ogeler icin AutomaticKeepAlive ve RepaintBoundary
24ListView.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 sinirla
2Image.network(
3 imageUrl,
4 cacheWidth: 300, // Decode edilecek genislik
5 cacheHeight: 300, // Decode edilecek yukseklik
6 fit: BoxFit.cover,
7);
8 
9// cached_network_image paketi ile onbellekleme
10CachedNetworkImage(
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.xml
3//
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 calistirin
2flutter run --profile
3 
4# DevTools'u acin
5flutter pub global activate devtools
6dart devtools

DevTools 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 yonetimi
2class ImageCacheManager {
3 static void configureCacheSize() {
4 // Onbellek boyutunu sinirla
5 PaintingBinding.instance.imageCache.maximumSize = 100; // maks 100 gorsel
6 PaintingBinding.instance.imageCache.maximumSizeBytes = 50 * 1024 * 1024; // 50MB
7 }
8 
9 static void clearCache() {
10 PaintingBinding.instance.imageCache.clear();
11 PaintingBinding.instance.imageCache.clearLiveImages();
12 }
13}
14 
15// Stream subscription temizligi
16class MyWidget extends StatefulWidget {
17 const MyWidget({super.key});
18 
19 @override
20 State createState() => _MyWidgetState();
21}
22 
23class _MyWidgetState extends State {
24 late final StreamSubscription _subscription;
25 
26 @override
27 void initState() {
28 super.initState();
29 _subscription = someStream.listen((data) {
30 // data isle
31 });
32 }
33 
34 @override
35 void dispose() {
36 _subscription.cancel(); // KRITIK: Temizlemeyi unutma!
37 super.dispose();
38 }
39 
40 @override
41 Widget build(BuildContext context) {
42 return const SizedBox();
43 }
44}

9. Network Optimizasyonu

dart
1// HTTP isteklerini optimize etme
2class 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 loglama
11 _dio.interceptors.add(LogInterceptor(
12 requestBody: true,
13 responseBody: true,
14 ));
15 
16 // Cache interceptor
17 _dio.interceptors.add(DioCacheInterceptor(
18 options: CacheOptions(
19 store: MemCacheStore(),
20 maxStale: const Duration(minutes: 5),
21 ),
22 ));
23 }
24 
25 // Paralel istekler
26 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 et
2flutter build apk --analyze-size
3 
4# App bundle (daha kucuk)
5flutter build appbundle
6 
7# Obfuscation ile boyutu azalt
8flutter build apk --obfuscate --split-debug-info=build/debug-info
9 
10# Kullanilmayan kaynaklari tespit et
11flutter pub run dart_code_metrics:metrics analyze lib

Boyut 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:

Etiketler

#Flutter#Performance#Optimization#Dart#DevTools#Impeller
Muhittin Çamdalı

Muhittin Çamdalı

Senior iOS Developer

12+ yıllık deneyime sahip iOS Developer. Swift, SwiftUI ve modern iOS mimarileri konusunda uzman. Apple platformlarında performanslı ve kullanıcı dostu uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

Bunu da begenebilirsiniz