Flutter mobil uygulama geliştirme projelerinde ilk ekran ve ilk geçişlerde görülen shader jank sorununu DevTools, FrameTiming ve renderer farklarıyla ölçün; Skia ve Impeller için doğru warm-up sınırlarını belirleyin.
Flutter Mobil Uygulama Geliştirmede Shader Jank İzleme ve Warm-up
Flutter mobil uygulama geliştirmede shader jank'i frame düzeyinde ayırmak
Shader jank, Dart tarafındaki widget build süresinden farklı bir arızadır: ilk kez kullanılan bir gradient, blur, clip veya özel fragment programı raster iş parçacığında derleme ya da pipeline oluşturma maliyeti çıkarabilir. DevTools Performance ekranında aynı frame için UI ve Raster sürelerini karşılaştırın. UI 4 ms iken Raster 28 ms ise sorun çoğunlukla state güncellemesi değil, render backend'indedir. Ölçümü debug modda yapmayın; debug assertion'ları, JIT ve servis protokolü maliyeti sonuçları bozar. Hedef cihazda profile modunu kullanın:
flutter run --profile
# Uygulama açıkken DevTools - Performance - Record
# Hedef akış: uygulamayı aç, ilk kez blur'lu listeye gir, geri çık, tekrar girSayısal bir başlangıç çizgisi için belirli bir kullanıcı akışının sadece ilk geçişini kaydedin. Aşağıdaki callback, raster süresi 16.67 ms eşiğini geçen frame'leri loglar. 60 Hz dışındaki ekranlarda eşiği cihaz yenileme hızına göre değiştirin; örneğin 120 Hz cihazda bütçe yaklaşık 8.33 ms'dir. Önce ve sonra karşılaştırmasında ortalama yerine en az 30 temiz çalıştırmanın p95 raster süresini ve 16.67 ms üzerindeki frame sayısını saklayın. Android'de kalıcı shader önbelleğinin deneyi kirletmesini önlemek için her ölçüm turundan önce `adb shell pm clear com.example.app` çalıştırabilirsiniz.
import 'package:flutter/scheduler.dart';
void installFrameProbe() {
SchedulerBinding.instance.addTimingsCallback((frames) {
for (final frame in frames) {
final raster = frame.rasterDuration;
if (raster > const Duration(microseconds: 16670)) {
debugPrint('slow-raster=${raster.inMicroseconds}us '
'build=${frame.buildDuration.inMicroseconds}us');
}
}
});
}Skia shader kaydı ve cross platform mobil uygulama geliştirme sınırı
Skia renderer kullanan bir hedefte, gerçek kullanıcı akışında üretilen shader kayıtlarını toplamak için `--cache-sksl` kullanılabilir. Akışı yaparken yalnızca ana ekranı değil, farklı tema, görsel filtre, SVG ve animasyon durumlarını da tetikleyin; kayda girmeyen efekt ilk üretimde yine raster sıçraması yaratır. Ardından üretilen dosyayı sürüm artefaktına bağlayın:
flutter run --profile --cache-sksl
# Uygulamadaki kritik akışları bir kez çalıştırın
flutter build apk --bundle-sksl-path flutter_01.sksl.jsonBu yöntem bir evrensel cache dosyası değildir. SKSL kaydı GPU sürücüsü ve renderer davranışına bağlıdır; bir cihazda toplanan dosyayı tüm Android GPU ailelerine körlemesine dağıtmak görsel hata veya beklenen faydanın alınamaması riski taşır. Ayrıca Impeller kullanan hedeflerde SKSL bundle iş akışını çözüm varsaymayın; DevTools'ta backend'i ve gerçek cihazdaki Raster track'i doğrulayın. Cross platform mobil uygulama geliştirme test matrisinde en az bir düşük seviye Android GPU, bir üst seviye Android GPU ve fiziksel iOS cihazı için ilk-geçiş p95 değerini ayrı tutun. Emulator GPU'su, üretim sürücüsündeki pipeline maliyetini güvenilir biçimde temsil etmez.
Flutter state management ile karıştırılmayan uygulama içi shader warm-up
Kontrollü bir alternatif, uygulamanın ilk etkileşiminden önce gerçekten kullanılan basit shader'ları offscreen canvas üzerinde çizdirmektir. `ShaderWarmUp` ataması ilk frame'den önce yapılmalıdır; ilk route açıldıktan sonra atarsanız kullanıcı zaten maliyeti görmüştür. Aşağıdaki örnek linear gradient yolunu önceden tetikler. Uygulamanız `RadialGradient`, `ImageFilter.blur`, `FragmentProgram` veya farklı blend mode kullanıyorsa her biri için gerçek çizim yoluna yakın ayrı bir örnek gerekir.
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
class AppShaderWarmUp extends ShaderWarmUp {
@override
void warmUpOnCanvas(Canvas canvas) {
final paint = Paint()
..shader = ui.Gradient.linear(
const Offset(0, 0),
const Offset(320, 320),
const [Color(0xff1a73e8), Color(0xffd93025)],
);
canvas.drawRect(const Rect.fromLTWH(0, 0, 320, 320), paint);
}
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
PaintingBinding.instance.shaderWarmUp = AppShaderWarmUp();
runApp(const App());
}Warm-up, flutter state management katmanındaki gereksiz rebuild sorununu düzeltmez. Riverpod, Bloc veya başka bir çözüm aynı `ShaderMask` ağacını her state değişiminde yeniden kuruyorsa, tekrar eden `saveLayer` ve compositing maliyeti shader derlemesiyle karışabilir. DevTools'ta önce Raster track'inde ilk kullanımda tek seferlik büyük sıçrama olup olmadığını teyit edin; sonra Flutter Inspector Rebuild Stats ile widget yeniden kurulmalarını inceleyin. Warm-up ekledikten sonra başlangıç süresini de ölçün: ilk etkileşimden önce 180 ms ek maliyet, ilk liste kaydırmasındaki 25 ms sıçramadan daha kabul edilebilir olmayabilir. Bu karar, p95 ilk-geçiş raster süresi ve cold-start süresi birlikte raporlanarak verilir.
dart programlama eğitimi kapsamında render maliyetini azaltan widget seçimi
Shader jank'i gizlemek yerine shader tetikleyen render ağacını azaltmak çoğu zaman daha güvenilir bir çözümdür. Özellikle kaydırılan her hücrede `ShaderMask` ve `BackdropFilter` kullanmak, offscreen layer oluşturulmasına ve arka plan örneklenmesine neden olabilir. Tekrarlanan gradient dekorasyonunu mümkünse `DecoratedBox` ile çizdirin; bu yaklaşım maskeleme için child'ı ayrı bir katmana alma ihtiyacını ortadan kaldırabilir.
// Daha pahalı olabilen yaklaşım: her kartta ShaderMask
ShaderMask(
shaderCallback: (rect) => const LinearGradient(
colors: [Color(0xff1565c0), Color(0xff42a5f5)],
).createShader(rect),
child: const Icon(Icons.star, color: Colors.white),
)
// Kart arka planı için doğrudan dekorasyon
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xff1565c0), Color(0xff42a5f5)],
),
),
child: SizedBox(width: 48, height: 48),
)Deneyimli ekiplerin sık yaptığı hata, yalnızca ilk frame'i benchmark etmektir. Liste hücreleri ilk kez viewport'a girdiğinde yeni blur yarıçapı, clip tipi veya fragment shader parametre kombinasyonu ayrı pipeline yollarını tetikleyebilir. `flutter eğitimi` veya `flutter kursu` örneklerinde görülen statik ekran testleri bu nedenle yeterli değildir. En azından aşağıdaki akışları CI'da gerçek cihaz çiftliğinde kaydedin: cold start, ilk hero geçişi, listenin son hücresine hızlı scroll ve tema değişimi. Bu test senaryolarını Dart ile sabit veri kullanarak deterministik hale getirmek, `dart programlama eğitimi` sırasında öğrenilen veri üretimi becerisinin doğrudan performans testine uygulanmış halidir.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Sık Sorulan Sorular
Flutter eğitimi sırasında shader jank ile normal widget rebuild maliyetini nasıl ayırırım?
Uygulamayı `flutter run --profile` ile açın ve DevTools Performance kaydında UI ile Raster sürelerini ayrı inceleyin. Yüksek buildDuration genellikle widget ağacına, yüksek rasterDuration ise çizim, shader veya layer işlemine işaret eder. `SchedulerBinding.addTimingsCallback` ile iki süreyi ayrı loglayıp aynı kullanıcı akışında p95 hesaplayın.
Flutter kursu projelerinde --cache-sksl dosyasını her platform için kullanabilir miyim?
Hayır. `--cache-sksl` iş akışı Skia renderer için anlamlıdır ve kayıt, hedef GPU ile sürücü koşullarından etkilenir. Impeller kullanan hedeflerde SKSL bundle'ı çözüm kabul etmeyin. Android ve iOS için fiziksel cihazda DevTools Raster track'iyle ayrı ölçüm yapın; SKSL dosyasını da farklı GPU ailelerine kontrolsüz dağıtmayın.
Flutter state management değişikliği ilk açılıştaki gradient takılmasını çözer mi?
Tek başına çözmez. State management, gereksiz rebuild sayısını azaltabilir; ancak ilk gradient veya fragment programı kullanımındaki raster tarafı maliyetini ortadan kaldırmaz. Önce DevTools'ta ilk kullanımda tek seferlik Raster sıçramasını doğrulayın, sonra `ShaderWarmUp` veya renderer'a uygun shader önbelleği yaklaşımını deneyin.
Cross platform mobil uygulama geliştirme için shader performans testi hangi cihazlarda yapılmalı?
En az bir düşük seviye Android, farklı GPU ailesine sahip ikinci bir Android ve fiziksel bir iOS cihazı kullanın. Her cihazda cold start sonrası ilk navigasyon, ilk scroll ve ilk filtreli ekran için 30 tekrar toplayın. Karar metriği olarak ortalama yerine p95 rasterDuration ve frame bütçesini aşan frame sayısını raporlayın.
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.



