Flutter mobil uygulama geliştirme projelerinde takılmaları yalnızca ortalama FPS ile değil, frame pacing, VSync gecikmesi ve UI thread zaman çizelgesiyle ölçün. DevTools, Perfetto ve frame bazlı state birleştirmeyi uygulayın.
Flutter Mobil Uygulama Geliştirmede Frame Pacing ve VSync Teşhisi
Flutter mobil uygulama geliştirmede FrameTiming ile gerçek kare bütçesi
Frame pacing sorunu, ortalama FPS'nin gizlediği düzensiz kare aralıklarıdır. 60 Hz ekranda iki VSync arasındaki teorik süre 16.67 ms, 120 Hz ekranda 8.33 ms'dir. Ancak hedef sadece build süresini bu sınırın altında tutmak değildir: UI thread'deki build ve raster thread'deki raster işlemlerinden biri VSync teslim anını kaçırırsa kullanıcı 16.67 ms yerine 33.34 ms aralıklı iki kare görür. Bir flutter eğitimi veya flutter kursu içinde FPS sayacını tek başına metrik kabul etmek yaygın ama hatalı bir pratiktir; p50 ile birlikte p95, p99 ve budget aşımı sayısı kaydedilmelidir.
Profil modunda FrameTiming örneklerini toplayıp ısınma dönemini dışarıda bırakın. Aşağıdaki kod, uygulama açılışından sonraki ilk 120 kareyi yok sayar ve sonraki 600 karede 16.67 ms'yi aşan build veya raster sürelerini sayar. Bu callback release davranışına yakın sonuç için debug yerine flutter run --profile ile çalıştırılmalıdır.
import 'dart:developer' as developer;
import 'dart:ui';
class FrameBudgetProbe {
static const budget = Duration(microseconds: 16667);
int _ignored = 0;
int _sampled = 0;
int _overBudget = 0;
void start() {
PlatformDispatcher.instance.onReportTimings = _onTimings;
}
void _onTimings(List<FrameTiming> timings) {
for (final timing in timings) {
if (_ignored++ < 120) continue;
if (_sampled++ >= 600) return;
final build = timing.buildDuration;
final raster = timing.rasterDuration;
if (build > budget || raster > budget) _overBudget++;
developer.log(
'build=${build.inMicroseconds}us '
'raster=${raster.inMicroseconds}us '
'over=$_overBudget/$_sampled',
name: 'frame_budget',
);
}
}
}FrameTiming yalnızca Flutter motorunun bildirdiği aşamaları kapsar; işletim sistemi compositor'ı, ekran yenileme modu ve SurfaceFlinger beklemeleri burada doğrudan görünmez. Bu nedenle bir karede build 4 ms ve raster 3 ms ölçülse bile kullanıcı takılma algılayabilir. Önce DevTools Performance görünümünde jank işaretli karelerin build mi raster mı olduğunu ayırın, sonra aynı kullanıcı akışını sistem iziyle doğrulayın. Ölçüm için tekrarlanabilir bir senaryo yazın: soğuk açılış sonrası 3 saniye bekle, listeyi 10 kez 800 px/s hızla kaydır, detay ekranını 10 kez aç-kapat.
DevTools ve Perfetto ile VSync kaçırmanın kaynağını ayırmak
Flutter DevTools'ta Performance sekmesini profil oturumuna bağlayın, ardından jank içeren bir kareyi seçin. UI grafiğinde yükselen süre Dart kodu, layout veya widget build kaynaklıdır; raster grafiğindeki yükseliş ise resim decode, clipping, compositing ya da GPU komutu hazırlama yönünde araştırılmalıdır. flutter run --profile --trace-skia komutu Skia komutlarını izlemeye ekler, fakat bu seçenek trace dosyasını büyüttüğü için yalnızca 5-10 saniyelik kontrollü kayıtlar alın.
Android tarafında Flutter dışındaki VSync gecikmesini görmek için aynı akışta Perfetto kaydı alın. Aşağıdaki komut 15 saniye boyunca scheduler, frekans ve grafik olaylarını cihazda toplar. Kayıttan sonra dosyayı Perfetto arayüzünde açıp uygulamanın ana thread'i, RenderThread, SurfaceFlinger ve Choreographer#doFrame dilimlerini aynı zaman ekseninde karşılaştırın.
adb shell perfetto -o /data/misc/perfetto-traces/flutter-frame.pftrace -t 15s sched freq gfx view
adb pull /data/misc/perfetto-traces/flutter-frame.pftrace .Buradaki kritik ayrım şudur: Dart UI thread'i VSync sonrası 20 ms meşgulse sorun uygulama tarafındadır. UI thread boşken SurfaceFlinger tarafında teslim gecikiyorsa, uygulamanın kareyi üretmiş olması ekrana zamanında geldiği anlamına gelmez. Ayrıca CPU frekansının düşük kaldığı ilk kaydırmada tekrar eden uzun scheduler slice'ları görürseniz, tek bir benchmark sonucunu yeterli saymayın. Her değişiklik için en az 10 tekrar alın; p95 kare aralığını, 16.67 ms üstü kare sayısını ve Perfetto'daki ana thread en uzun slice değerini önce-sonra tablosuna yazın.
Flutter state management akışlarını kare başına bir kez birleştirme
WebSocket, konum veya arama sonucu akışları saniyede onlarca state güncellemesi üretebilir. Flutter state management katmanının her olayı anında dinleyiciye iletmesi, tek bir ekranda kullanıcıya hiç görünmeyecek ara state'ler için birden fazla build planlar. Sorun yalnızca widget sayısı değildir: her bildirim inherited dependency çözümlemesi, layout geçişi ve semantik güncellemesi başlatabilir. Çözüm, veri kaybını kabul edebilen görsel state için son değeri bir sonraki frame'e kadar birleştirmektir.
Aşağıdaki FrameCoalescedNotifier, bir frame içinde gelen birden fazla değerden yalnızca sonuncusunu yayınlar. Sipariş oluşturma veya bakiye hareketi gibi her olayın işlenmesi gereken domain olaylarında bunu kullanmayın; burada birleştirilen şey sadece ekranda gösterilen projection'dır.
import 'package:flutter/scheduler.dart';
import 'package:flutter/foundation.dart';
class FrameCoalescedNotifier<T> extends ChangeNotifier {
FrameCoalescedNotifier(this._value);
T _value;
bool _scheduled = false;
bool _disposed = false;
T get value => _value;
void publish(T next) {
_value = next;
if (_scheduled) return;
_scheduled = true;
SchedulerBinding.instance.scheduleFrameCallback((_) {
_scheduled = false;
if (!_disposed) notifyListeners();
});
}
@override
void dispose() {
_disposed = true;
super.dispose();
}
}scheduleFrameCallback callback'i frame başlangıcında çalıştırır; bu nedenle dinleyicinin tetiklediği build aynı frame pipeline'ına dahil olabilir. Buna karşılık her event için addPostFrameCallback kullanmak genellikle çözüm değildir: callback paint sonrasında çalışır, pahalı iş yaparsa bir sonraki VSync için kalan süreyi tüketir. Bu ayrım dart programlama eğitimi içeriklerinde event loop anlatılırken çoğu zaman atlanır. DevTools'ta değişiklikten önce saniyede 80 state emisyonu ve 80 build, değişiklikten sonra aynı ekranda en fazla ekran yenileme hızı kadar build görmeyi hedefleyin.
Cross platform mobil uygulama geliştirme için frame pacing regresyon testi
Cross platform mobil uygulama geliştirme sürecinde Android ve iOS cihazlarını aynı sayısal bütçeyle değerlendirmek yanıltıcı olabilir; yenileme hızı, termal durum ve compositor davranışı değişir. Bunun yerine cihaz sınıfı başına ayrı baseline tutun. Örneğin 60 Hz test havuzunda p95 build süresi 8 ms, p95 raster süresi 10 ms ve 600 örnekte en fazla 12 budget aşımı; yüksek yenileme hızlı havuzda ise ekranın gerçek frame aralığının yüzde 70'i kadar bir hedef tanımlayın.
CI'da ölçümü tekrarlanabilir hale getirmek için entegrasyon testinin etkileşim akışını sabitleyin ve profil APK'sını gerçek cihazda çalıştırın. Örnek komut dizisi aşağıdaki gibi olabilir. Testte sabit fixture veri kullanın, ağ çağrılarını mock'layın ve cihazın güç tasarrufu modunu test koşullarında kapatın; aksi halde CPU frekans ölçeklemesi sonuçları karşılaştırılamaz hale getirir.
flutter build apk --profile
flutter test integration_test/scroll_benchmark_test.dart -d emulator-5554 --dart-define=BENCHMARK_FIXTURE=true
adb logcat -d -s frame_budget:D '*:S' > frame-budget.logÖnce-sonra karşılaştırmasında sadece ortalama süreyi raporlamayın. Örneğin frame başına state birleştirmeden önce 600 örneğin 74'ünde 16.67 ms üstü build, sonrasında 11'inde üstü build görülebilir; fakat raster p95 18 ms'ye çıktıysa değişiklik kabul edilmemelidir. Aynı değişiklik farklı cihazlarda ters etki yaratabilir. Bu nedenle PR eşiğini 'p95 build veya raster baseline'ın yüzde 10 üstüne çıkmasın ve budget aşımı mutlak olarak artmasın' şeklinde tanımlayın. Bu yaklaşım, flutter kursu projelerinde demo akıcılığı yerine üretim cihazlarındaki ölçülebilir teslim gecikmesini hedefler.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Sık Sorulan Sorular
Flutter mobil uygulama geliştirmede 60 FPS varken neden takılma görülür?
Ortalama FPS, 16.67 ms ve 33.34 ms aralıklı karelerin ortalamasını gizleyebilir. Profil modunda DevTools Frame Chart kullanın, 600 FrameTiming örneğinde p95 build ve raster sürelerini çıkarın. Ardından Perfetto'da UI thread, RenderThread ve SurfaceFlinger zamanlarını hizalayarak gecikmenin uygulama mı compositor mı olduğunu ayırın.
Flutter state management içinde çok sık gelen stream verisi nasıl çizilmelidir?
Ekranda sadece en güncel değer önemliyse state'i her stream olayında yayınlamak yerine SchedulerBinding.instance.scheduleFrameCallback ile frame başına tek bildirimde birleştirin. Ancak finansal hareket, mesaj teslimi veya audit kaydı gibi tüm olayların işlenmesi gereken domain akışlarında yalnızca UI projection'ını birleştirin, domain event'lerini düşürmeyin.
Flutter eğitimi sırasında performans testi debug modda yapılabilir mi?
Hayır. Debug moddaki assertion'lar, JIT çalışma biçimi ve ek diagnostic işlemler frame sürelerini üretim davranışından uzaklaştırır. flutter run --profile ile gerçek cihazda ölçün, ilk 120 kareyi ısınma olarak dışlayın ve aynı kaydırma senaryosunu en az 10 kez tekrarlayın.
Cross platform mobil uygulama geliştirme projelerinde Android ve iOS için aynı frame bütçesi kullanılmalı mı?
Sabit 16.67 ms eşiği yalnızca 60 Hz varsayımıdır. Test cihazının yenileme aralığını baz alın, p95 build ve raster sürelerini o bütçeye göre izleyin. Platformlar arasında tek bir skor yerine cihaz sınıfı başına baseline ve budget aşımı sayısı tutmak daha güvenilir karşılaştırma verir.
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.


