Flutter mobil uygulama geli?tirme s?re?lerinde 16,67 ms frame b?t?esini DevTools, Timeline ve widget yeniden ?izim verileriyle ?l??n; jank ?reten build, raster ve shader darbo?azlar?n? kod d?zeyinde ay?r?n.
Flutter Mobil Uygulama Geliştirmede Frame Budget ve Jank Analizi
Flutter mobil uygulama geliştirmede ölçülebilir frame bütçesi kurmak
60 Hz ekranda her frame için toplam bütçe 16,67 ms, 120 Hz ekranda ise 8,33 ms'dir. Flutter bu sürede UI isolate üzerinde Dart kodunu çalıştırır, ardından raster thread sahne ağacını GPU komutlarına dönüştürür. Ölçüme debug modda başlamayın: assert kontrolleri, JIT ve debug servisleri zamanlamayı değiştirir. Fiziksel cihazda profile artefact üretmek için aşağıdaki komutu çalıştırın; ardından DevTools'ta Performance sekmesinden kaydı açın.
flutter run --profile --trace-skia
# Ayrı bir terminalde:
dart devtoolsDevTools Frame Chart'ta kırmızı frame seçildiğinde önce baskın tarafı ayırın: UI grafiği yüksekse sorun çoğunlukla build, layout veya Dart hesaplamasıdır; Raster grafiği yüksekse clipping, blur, çok büyük katmanlar ya da shader derlemesi incelenmelidir. Bir değişiklik öncesi ve sonrası aynı fiziksel cihazda, aynı veri setiyle en az 30 saniyelik aynı kaydırma senaryosunu kaydedin. Karşılaştırmayı ortalama yerine 16,67 ms üzerindeki frame sayısı ve en kötü p95 UI/Raster süresiyle yapın; tek bir ortalama, birkaç 80 ms sıçramayı gizler.
Flutter state management ile gereksiz rebuild zincirlerini kesmek
Flutter state management seçiminde kritik ölçüt store'un adı değil, bir state değişikliğinin kaç widget'ı build etmeye zorladığıdır. Örneğin Provider ile tüm ürün listesine bağlı bir üst widget, sepetteki adet değiştiğinde yüzlerce görünür satırı yeniden kurabilir. DevTools Widget Rebuild Stats'ı açın ve yalnızca sepet rozeti değişirken yeniden oluşturulan widget sayısını kaydedin. Ardından dinlemeyi selector düzeyine indirin; context.select, seçilen değer eşit kaldığında ilgili widget'ın rebuild'ini atlar.
class CartBadge extends StatelessWidget {
const CartBadge({super.key});
@override
Widget build(BuildContext context) {
final itemCount = context.select(
(store) => store.totalItemCount,
);
return Badge(label: Text('$itemCount'));
}
} Buradaki incelik, selector'dan her build'de yeni bir List, Map veya eşitlik tanımlamamış immutable DTO döndürmemektir. Örneğin context.select((CatalogStore s) => s.visibleProducts.where(...).toList()) her seferinde yeni referans üretir ve seçici anlamsızlaşır. Türetilmiş koleksiyonu store içinde memoize edin ya da package:collection içindeki ListEquality ile değer eşitliği olan immutable view model kullanın. Bu ayrım, bir flutter eğitimi veya flutter kursu projesinde 'state değişti, ekran güncellendi' seviyesinden, rebuild yüzey alanını sayısal olarak denetlemeye geçiştir.
Raster thread darboğazları: RepaintBoundary, clip ve görsel maliyeti
Kaydırılan bir ListView içinde sabit kalan ama sık güncellenen bir grafik, tüm listenin repaint edilmesine neden oluyorsa grafiği RepaintBoundary ile ayırın. Etkiyi DevTools'taki Highlight Repaints ve Checkerboard Raster Cache Images seçenekleriyle doğrulayın: değişiklikten önce kaydırmada listenin geniş alanı yanıp sönüyor, sonrasında yalnızca grafik alanı boyanıyorsa izolasyon işe yaramıştır.
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
title: Text(item.title),
trailing: RepaintBoundary(
child: LiveSparkline(points: item.priceHistory),
),
);
},
);RepaintBoundary her widget'a eklenen evrensel bir hızlandırıcı değildir. Sınır, ayrı layer ve bazı durumlarda raster cache oluşturur; her frame değişen animasyonlu bir alt ağacı sınırlamak cache'i sürekli geçersiz kılar ve GPU belleği tüketir. Ayrıca Clip.antiAliasWithSaveLayer offscreen buffer gerektirebilir. Bir kartta yalnızca yuvarlatılmış köşe gerekiyorsa önce ClipRRect(clipBehavior: Clip.antiAlias) deneyin; DevTools'ta Raster süresi düştüğünü görmeden saveLayer kullanan efektleri korumayın. Büyük bulanıklıklarda BackdropFilter yerine önceden bulanıklaştırılmış varlık ya da küçük, sınırlı bir clip alanı seçmek daha öngörülebilir maliyet verir.
Dart programlama eğitimi perspektifiyle UI isolate işini izlemek
UI isolate üzerinde JSON ayrıştırma, görsel dönüştürme veya büyük sıralama yapmak input event'lerinin ve frame callback'lerinin gecikmesine yol açar; sorun 'Dart yavaş' olduğu için değil, aynı event loop'un frame üretmesi gerektiği için oluşur. DevTools CPU Profiler'da kaydırma sırasında jsonDecode, List.sort veya uygulama fonksiyonunuzun self time'ını görün. Tek seferlik, yeterince büyük JSON dönüşümünü compute ile worker isolate'a taşıyın; ancak isolate'a gönderilen nesnelerin kopyalandığını, küçük payload'larda kopyalama maliyetinin kazancı silebileceğini unutmayın.
Future> loadProducts(String body) {
return compute(parseProducts, body);
}
List parseProducts(String body) {
final raw = jsonDecode(body) as List;
return raw
.cast
Önce-sonra kaydında yalnızca toplam işlem süresine bakmayın: Timeline'da UI thread üzerindeki uzun task'ın kaybolduğunu ve frame sayısının iyileştiğini doğrulayın. Daha ayrıntılı işaretleme için dart:developer ile kritik akışı Timeline'a yazın; bu teknik dart programlama eğitimi içinde özellikle async kodun görünmez maliyetini açığa çıkarır.
import 'dart:developer' as dev;
Future refreshCatalog() async {
final task = dev.TimelineTask()..start('catalog.refresh');
try {
final response = await api.fetchCatalog();
await repository.persist(response);
} finally {
task.finish();
}
} Cross platform mobil uygulama geliştirme için cihaz bazlı doğrulama
Cross platform mobil uygulama geliştirme sırasında aynı trace'i en az bir düşük/orta sınıf Android cihaz ve hedef iOS cihazında alın; GPU sürücüsü, ekran yenileme hızı ve metin rasterizasyonu farklı olduğundan emülatör sonucu yayın kararı için yeterli değildir. Otomatik tekrar için integration_test ile deterministik bir kaydırma akışı oluşturun, ardından CI'da profile modda cihaz çiftliğinde trace arşivleyin. Aşağıdaki test, zaman tabanlı rastgele gesture yerine aynı piksel mesafesini uygular; bu da öncesi/sonrası kıyasını daha anlamlı yapar.
testWidgets('catalog scroll trace', (tester) async {
await tester.pumpWidget(const App());
await tester.fling(
find.byKey(const Key('catalog_list')),
const Offset(0, -1800),
2400,
);
await tester.pumpAndSettle();
});Shader kaynaklı ilk-etkileşim sıçramaları için uygulamanın en sık kullanılan akışını gerçek cihazda kaydedip derleme hattınızın desteklediği shader warm-up yaklaşımını ayrıca test edin; yalnızca başlangıç ekranını ısıtmak, ürün detayındaki gradient veya blur shader'ını kapsamaz. DevTools'ta ilk dolaşım ile ikinci dolaşımı ayrı kaydedin: yalnızca ilkinde Raster spike görülüyorsa shader veya cache ısınması olasıdır; her ikisinde de görülüyorsa widget/layer yapısı incelenmelidir. Bu ayrım, flutter mobil uygulama geliştirme performans hatalarında kalıcı regressions ile ilk-kullanım maliyetini birbirine karıştırmayı önler.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Sık Sorulan Sorular
Flutter state management rebuild sayısı nasıl ölçülür?
Uygulamayı fiziksel cihazda flutter run --profile ile açın, DevTools'ta Widget Rebuild Stats'ı etkinleştirin ve tek bir state aksiyonunu çalıştırın. Önce üst seviyede watch kullanan alanları kaydedin; sonra rozet, satır veya fiyat gibi küçük alanları context.select, Riverpod select ya da Bloc buildWhen ile ayırıp aynı aksiyonda rebuild sayısını karşılaştırın.
Flutter kursu projelerinde RepaintBoundary ne zaman kullanılmalı?
DevTools Highlight Repaints, bir alt widget değişirken gereğinden büyük bir alanın yeniden boyandığını gösteriyorsa kullanın. Örneğin canlı grafik veya video kontrolü liste satırlarından bağımsız repaint ediyorsa sınır anlamlıdır. Her animasyonlu widget'a eklemeyin: raster cache sürekli invalidation alıyorsa Frame Chart'ta Raster süresi düşmek yerine artabilir.
Dart programlama eğitimi için compute ile isolate kullanımı ne zaman mantıklı?
CPU Profiler'da UI isolate üzerinde frame'i aşan JSON parse, kriptografik dönüşüm veya büyük sıralama görüyorsanız adaydır. Önce işi Timeline ile ölçün; sonra compute ile saf, serializable girdi alan bir fonksiyona taşıyın. Birkaç kilobaytlık hızlı işler için isolate mesaj kopyalama ve başlatma maliyeti nedeniyle doğrudan çalıştırmak daha kısa sürebilir.
Flutter mobil uygulama geliştirmede jank için önce UI mı Raster mı incelenmeli?
DevTools Frame Chart'ta kırmızı frame'in yüksek grafiğine bakın. UI yüksekse build, layout, senkron Dart kodu ve state aboneliklerini CPU Profiler ile inceleyin. Raster yüksekse Highlight Repaints, checkerboard seçenekleri, clip davranışı, blur ve büyük image decode maliyetlerini inceleyin. İki tarafı aynı anda değiştirmek, hangi müdahalenin etkili olduğunu belirsizleştirir.
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.



