• 29.10.2026 05:18:00
  • İbrahim Gökyar

Bu rehber, Flutter mobil uygulama geliştirme projelerinde metin layout ve font yükleme kaynaklı jankleri ölçme, profil etme ve somut düzeltmelerle azaltmayı gösterir. flutter eğitimi ve dart programlama eğitimi kapsamında uygulamalı örnekler içerir.

Flutter metin ve font optimizasyonu - mobil uygulama jank azaltma rehberi

Profilleme: Text layout maliyetini tespit etmek (DevTools ve komutlar)

Özet: Metin kaynaklı gecikmeleri tespit etmek için Flutter DevTools timeline, CPU profiler ve dart:developer ile uyumlu ölçümleri kullanın. Somut adımlar:

  • 1) Uygulamayı profil modunda başlat: flutter run --profile.
  • 2) DevTools'u açın: dart devtools veya IDE entegre DevTools. Performance -> Record ile ekranı 8-15 saniye kaydedin.
  • 3) Timeline filtrelerinde "Frame" ve "Raster" olaylarını açın, arama kutusuna "TextLayout" veya "Paragraph" yazın ve ilgili eventlerin toplam süresini not edin.
Bu adımlar gerçek zamanlı sayısal değer verir; örnegin toplam TextLayout süresi 200ms ise hedefiniz 50ms altına düşürmektir.

DevTools dışında otomatik ölçüm için dart:developer ile kendi zamanlamanızı alabilirsiniz. Örnek:

import 'dart:developer' as developer;

void buildSomething() {
  developer.Timeline.startSync('myTextBuild');
  // metin oluşturma / layout işlemleri
  developer.Timeline.finishSync();
}
Bu custom event ler DevTools timeline'ında görünür ve TextLayout ile ilişkili işlemleri ayrıştırmanıza yardımcı olur.

Font yükleme, fallback ve pyftsubset ile boyut azaltma - platform farkları

Font fallback ve emoji gibi heterojen karakter setleri, HarfBuzz bazlı şekillendirme ve font bulma algoritmalarını tetikler; bu da her layout için ekstra I/O ve CPU maliyeti getirir. Çözüm: gereksiz glifleri çıkararak font subset oluşturmak ve pubspec ile sabit yükleme yapmak. Örnek adımlar:

  • python pip ile fonttools kurun: pip install fonttools
  • ttf dosyasını subsetleyin (sadece uygulamada gereken Unicode aralıkları): pyftsubset Roboto-Regular.ttf --unicodes=U+0020-007E,U+0400-04FF --output-file=Roboto-subset.ttf
  • pubspec.yaml'e ekleyin:
fonts:
  - family: RobotoSubset
    fonts:
      - asset: fonts/Roboto-subset.ttf
Bu yaklaşımla APK/IPA içindeki font ağırlığını sayısal olarak azaltabilirsiniz; "before/after" ölçümü için du -sh build/app/outputs veya IPA içindeki font dosya boyutlarını kontrol edin.

Cross platform mobil uygulama geliştirme senaryosunda Android ve iOS farklı font fallback davranışı gösterir; bu yüzden subset uygulanmış fontları her iki platformda da test ederek görsel bozulma olup olmadığını inceleyin. Özellikle emoji ve CJK karakterlerini ayrı font paketleriyle yönetmek, her frame'de fallback maliyetini düşürür.

Paragraph ve TextPainter cache ile tekrar layout azaltma - uygulamalı örnek

RichText veya sık güncellenen ListView elemanlarında her frame'de yeniden Paragraph oluşturulması maliyetli olabilir. Etkili bir çözüm, sabit metinler için Paragraph veya TextPainter örneklerini constraint ile cache etmektir. Aşağıdaki CustomPainter örneği, width constraint ile keylenen TextPainter cache'i gösterir ve her paint çağrısında yeniden layout yapmayı engeller:

class CachedTextPainter {
  final Map _cache = {};

  TextPainter getPainter(String text, TextStyle style, double maxWidth) {
    final key = '${text.hashCode}|${style.hashCode}|$maxWidth';
    if (_cache.containsKey(key)) return _cache[key]!;
    final tp = TextPainter(
      text: TextSpan(text: text, style: style),
      textDirection: TextDirection.ltr,
      maxLines: 1,
    );
    tp.layout(maxWidth: maxWidth);
    _cache[key] = tp;
    return tp;
  }
}

// Kullanım: CustomPainter.paint içinde
final painter = cachedTextPainter.getPainter('Merhaba', style, size.width);
painter.paint(canvas, Offset.zero);

Neden çalışır: TextPainter.layout çağrısı O(n) karakter maliyetine sahip ve HarfBuzz işlemini tetikler; cache ile aynı constraints ve style altındaki tekrar layout'ları tamamen atlayabilirsiniz. Profilleme sonrası DevTools timeline'da TextLayout event sayısının ve toplam süresinin düştüğünü göreceksiniz.

RepaintBoundary ve picture/image cache ile layer maliyetini düşürme

Statik veya nadiren değişen metin bloklarını ayrı bir layer'a alıp raster cache'e sokmak, GPU tarafında tekrar rasterize maliyetini minimize eder. Pratik yaklaşım: widget'ı RepaintBoundary ile sarın ve gerektiğinde bir kez toImage ile görüntü alarak Image widget ile gösterin. Bu işlem için örnek kod:

Future captureAsImage(GlobalKey key, double pixelRatio) async {
  final boundary = key.currentContext!.findRenderObject() as RenderRepaintBoundary;
  final uiImage = await boundary.toImage(pixelRatio: pixelRatio);
  final byteData = await uiImage.toByteData(format: ui.ImageByteFormat.png);
  final codec = await ui.instantiateImageCodec(byteData!.buffer.asUint8List());
  final frame = await codec.getNextFrame();
  return frame.image;
}

// Widget:
RepaintBoundary(
  key: _textKey,
  child: Text('Sabit metin', style: TextStyle(...)),
)

Not: toImage maliyetli bir işlemdir ve UI thread'i bloke edebilir; bu yüzden uygulamada bunu startup sırasında veya kullanıcı etkileşimi dışındaki zamanlarda yapın. Alternatif olarak RepaintBoundary'i bırakarak Flutter'ın raster cache karar mekanizmasına güvenebilir ve sık değişmeyen widgetleri 'isolate' etkilenmeyecek şekilde izole edebilirsiniz. DevTools'ta Raster Cache bölümünü açıp 'cache hit/miss' oranını kontrol edin.

KPI'lar, otomasyonlu karşılaştırma ve yol haritası

Başarınızı ölçmek için somut KPI'lar belirleyin: örn. 'TextLayout toplam süresi < 50ms' veya 'ortalama frame build süresi < 12ms'. Otomatik karşılaştırma için trace export edip basit filtrelerle analiz yapabilirsiniz. DevTools'tan export edilen trace.json dosyasını jq ile süzmek için örnek komut:

cat trace.json | jq '.traceEvents[] | select(.name=="TextLayout" or .name=="Paragraph" ) | {name, dur, ts}' > text_events.json

# Toplam süreyi ms cinsinden hesaplamak için
cat text_events.json | jq 'map(.dur) | add / 1000'

Yol haritası önerisi:

  • 1. Profil: 10 saniye kayıt, TextLayout süresini ölç.
  • 2. Ön işlem: font subset + pubspec sabitleme.
  • 3. Uygulama: TextPainter/Paragraph cache uygulama.
  • 4. Raster: RepaintBoundary veya toImage ile layer cache alma.
  • 5. Doğrulama: aynı senaryoyu tekrar profile edip 'önce/sonra' karşılaştırması yapın. DevTools'ta frame build ve raster event sayıları, memory snapshot ve GPU thread zamanlarını karşılaştırın.
Bu adımları otomasyon testlerinize (integration_test + flutter drive --profile) ekleyerek regressiyon guard koyabilirsiniz.

İlgili Eğitim

Flutter Eğitimi

Sık Sorulan Sorular

flutter kursu sırasında metin optimizasyonu konusunu uygulamalı nasıl öğrenebilirim?

Bir flutter kursu veya flutter eğitimi seçerken, derslerin DevTools ile profil örnekleri, pyftsubset gibi araçların kullanıldığı uygulamalı egzersizleri içerdiğinden emin olun. Örneğin eğitimin bir modülünde flutter run --profile ile timeline kaydı alma, trace export etme ve font subsetleme (fonttools) gibi adımlar yer almalı.

dart programlama eğitimi alırken Paragraph cache ve TextPainter gibi low-level API'leri öğrenmek gerekli mi?

Evet; yüksek performanslı uygulamalar için widget seviyesinin ötesinde TextPainter, Paragraph ve RepaintBoundary gibi API'leri bilmek pratik fayda sağlar. Öneri: küçük bir demo yazıp TextPainter cache mantığını uygulayın ve DevTools timeline ile TextLayout süresini ölçün.

flutter state management ile metin performansı arasındaki ilişki nedir, state yönetimi jank'i nasıl etkiler?

State management seçimi doğrudan hangi widgetlerin rebuild edileceğini belirler. Fazla geniş kapsamlı rebuild'ler metin layout'u tekrar tetikleyerek jank yaratır. Çözüm: seçici dinleme (selective listening), const widget kullanımı, ve metni RepaintBoundary ile izole etmektir. Örnek: Provider veya Riverpod'ta sadece gerekli alt parçaları dinleterek TextPainter yeniden layout sayısını azaltabilirsiniz.

cross platform mobil uygulama geliştirme içinde font fallback neden daha maliyetli olabilir?

Android ve iOS farklı font fallback ve şekillendirme davranışlarına sahiptir; bir platformda bulunmayan glifler diğerinde farklı fonta yönlendirip ek şekillendirme tetikleyebilir. Bu yüzden subset veya platforma özel font paketleri kullanmak, hem boyut hem de frame maliyeti açısından fayda sağlar. Test için aynı trace senaryosunu her iki platformda da çalıştırın ve DevTools trace karşılaştırması yapı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.

Opendart Akademi llms.txt

📚 Bu konuyu Opendart Akademi'de öğrenin: Flutter eğitimi · Flutter eğitimi hakkında · YouTube video dersleri · Abone ol