Performance

React Native Performance Profiling

PerformanceProfiling

JS FPS ile UI FPS ayrımı, TTI ölçümü, Perfetto/Instruments ile darboğaz sınıflandırması. Önce metrik, sonra patch.

EG

Emre Gürbüz

31 Temmuz 2026 · 4 dk okuma

React Native’de performans tartışmalarının çoğu ölçümsüzdür: “FlatList yavaş”, “New Arch açınca düzelir”. Senior refleks tersidir — önce metrik, sonra hipotez, sonra patch.

Yanlış katmanı optimize etmek — UI thread problemini React.memo ile “çözmek” — en pahalı hatadır.

İki FPS vardır: JS ve UI

Tek bir “FPS” sayısı yanıltıcıdır. İki bağımsız frame bütçesi vardır (~16ms @ 60Hz):

MetrikNe ölçerDüşükse tipik suçlu
JS FPSJavaScript threadAğır render, büyük JSON parse, sync JSI suiistimali
UI FPSNative UI threadOverdraw, blur, layout thrash, image decode, worklet overload

JS 60 iken UI 40 olabilir — veya tersi. Perf Monitor veya platform profiler ile ayırın. Scroll jank genelde UI’de; liste filtreleme gecikmesi JS’te.

Neden ayrım kritik?

New Architecture (Fabric / Turbo) bazı UI maliyetlerini düşürür; JS render patolojisini iyileştirmez. Metrik ayrımı doğru müdahale katmanını seçtirir.

TTI ve cold start

TTI (Time to Interactive — etkileşilebilir ilk ekrana süre) bileşenleri:

  1. Process start + native init
  2. Hermes .hbc (bytecode) load ve VM init
  3. React root mount + ilk render
  4. İlk data (cache hit vs network)

Araç notu:

# Android: Perfetto trace + logcat ActivityManager displayed
# iOS: Instruments App Launch template + Time Profiler

Optimizasyon sırası genelde: eager native init azalt → bundle boyutu / inlineRequires → ilk ekran ağacını küçült → data prefetch. “Tüm tab navigator’ı hemen mount” anti-pattern’ini ölçmeden savunmayın.

TTI’yi p50 ve p95 olarak raporlayın. Ortalama yanıltır.

Cold vs warm start

Cold: process yok, sıfırdan. Warm: process bellekte. Kullanıcı ilk izlenimi cold start’a bakar.

Araç seti

JavaScript

  • React DevTools Profiler: commit süreleri, hangi component ne kadar render oldu
  • Hermes sampling profiler: JS CPU hot spot
  • Hermes heap snapshot: memory leak vs cache

Android

  • Perfetto / systrace: JS Thread, UI Thread, Choreographer
  • Android Studio Profiler: native + ART
  • GPU Rendering profile: overdraw
  • Macrobenchmark (CI): regresyon

iOS

  • Instruments: Time Profiler, Allocations, Core Animation
  • MetricKit (production): gerçek kullanıcı TTI

Reanimated kullanan ekranlarda JS FPS iyi, UI FPS düşük → worklet veya layout animasyonu şüpheli.

Darboğaz sınıfları

1. Gereksiz re-render

Context god-object, inline style={{}} ile memo kırılması. Müdahale: context split, selector pattern, bilinçli memo.

2. Liste performansı

Kötü key, getItemLayout eksikliği, nested VirtualizedList. FlashList gibi alternatifleri ölçmeden adopt etmeyin.

3. Bridge / serileştirme fırtınası

Henüz Turbo’ya geçmemiş hot path’te saniyede yüzlerce native çağrı. Müdahale: batch API, Turbo Module migrasyonu.

4. Görsel yük

Dev boyut PNG, cache yok, simultaneous decode. FastImage + boyut optimizasyonu.

5. Navigation remount

Her focus’ta heavy screen remount. detachInactiveScreens, lazy screen options.

Metodoloji: runbook

  1. Repro yaz: cihaz, OS, adım adım
  2. Baseline kaydet: video + FPS overlay + trace
  3. Tek hipotez: birden fazla değil
  4. Tek değişiklik: PR’da tek optimizasyon
  5. Aynı trace ile karşılaştır
  6. Kazanç yoksa geri al

Golden trace senaryolarını repo’da saklayın.

New Architecture etkisi

Fabric/Turbo bazı senaryolarda jank’i azaltır. JS render patolojisini iyileştirmez. New Arch’a “perf projesi” diye geçmeyin; migrasyon ve perf ayrı paket olsun.

Production checklist

  • JS vs UI FPS ayrı raporlanıyor
  • Low-end Android cihazda ölçüldü
  • Release profili alındı (minify + Hermes + R8)
  • Memory leak vs intentional cache ayrımı yapıldı
  • Liste ekranları için scroll trace arşivlendi
  • TTI p50/p95 production metrik
  • Golden trace senaryoları dokümante
  • Optimizasyon PR’ları tek hipotez kuralına uyuyor

Özet

Performans tahmin değil, ölçüm işidir. RN’de en pahalı hata yanlış katmanı optimize etmektir. JS FPS mi UI FPS mi düşük — bu sorunun cevabı tüm müdahale stratejinizi belirler.


Diğer yazılar