React Native Performans Rehberi: Yüksek Hızlı Uygulama Geliştirme
Yazar: Burak Balkı | Kategori: Performance | Okuma Süresi: 8 dk
Bu kapsamlı rehberde, React Native uygulamalarında performans optimizasyonu için mimari detaylar, render stratejileri, liste yönetimi ve bellek sızıntılarını...
React Native, tek bir JavaScript kod tabanıyla hem iOS hem de Android platformlarında yerel performans sunan uygulamalar geliştirmenize olanak tanır. Ancak, karmaşık arayüzler ve yoğun veri işleme süreçleri söz konusu olduğunda, doğru optimizasyon teknikleri uygulanmazsa performans darboğazları kaçınılmaz hale gelir. Bu rehberde, bir **React Native** uygulamasını en yüksek verimlilikle çalıştırmak için gereken stratejileri teknik detaylarıyla ele alacağız.
## React Native Mimarisini Anlamak
Performans optimizasyonuna girmeden önce, React Native'in çalışma prensibini anlamak gerekir. Geleneksel React Native mimarisi üç ana parçadan oluşur:
1. **JavaScript Thread:** İş mantığının ve React kodunun çalıştığı yer.
2. **Native Thread:** UI render işlemleri ve kullanıcı etkileşimlerinin yönetildiği platforma özel katman.
3. **The Bridge:** JavaScript ve Native tarafları arasındaki iletişimi sağlayan asenkron köprü.
Performans sorunlarının %90'ı, bu köprü (Bridge) üzerindeki aşırı trafikten kaynaklanır. Modern sürümlerde gelen **JSI (JavaScript Interface)**, bu köprüyü ortadan kaldırarak JavaScript'in native nesnelere doğrudan erişmesini sağlar.
## Render Performansını Optimize Etme
React Native'de en sık karşılaşılan sorun, gereksiz bileşen render (yeniden çizim) işlemleridir. Her render, CPU ve bellek tüketimi demektir.
### useMemo ve useCallback Kullanımı
Referans eşitliğini korumak, alt bileşenlerin gereksiz yere render edilmesini önler. Özellikle fonksiyonlar ve büyük objeler her render'da yeniden oluşturulmamalıdır.
```javascript
import React, { useMemo, useCallback } from 'react';
const ExpensiveComponent = ({ data, onPress }) => {
const processedData = useMemo(() => {
return data.map(item => ({ ...item, active: true }));
}, [data]);
const handlePress = useCallback(() => {
onPress(processedData);
}, [processedData, onPress]);
return ;
};
```
### React.memo ile Bileşen Sabitleme
Bir bileşenin props değerleri değişmediği sürece yeniden render edilmesini engellemek için `React.memo` kullanılmalıdır.
```javascript
const ListItem = React.memo(({ title }) => {
return {title} ;
});
```
## Liste Performansı: FlatList Optimizasyonu
Büyük veri setlerini listelerken `ScrollView` kullanmak tüm elemanları belleğe yükler. Bunun yerine `FlatList` kullanılmalı ve aşağıdaki parametrelerle optimize edilmelidir.
| Parametre | Açıklama | Önerilen Değer |
| :--- | :--- | :--- |
| `initialNumToRender` | İlk yüklemede kaç öğe çizileceği | 10 |
| `windowSize` | Görünür alan dışındaki tampon bölge | 5 |
| `maxToRenderPerBatch` | Her döngüde çizilecek maksimum öğe | 10 |
| `removeClippedSubviews` | Ekran dışı öğeleri bellekten atar | true |
```javascript
item.id}
getItemLayout={(data, index) => (
{ length: 70, offset: 70 * index, index }
)}
removeClippedSubviews={true}
initialNumToRender={10}
maxToRenderPerBatch={10}
/>
```
> **Not:** `getItemLayout` kullanımı, listenin eleman boyutlarını önceden bilmesini sağlayarak dinamik hesaplama yükünü ortadan kaldırır.
## Görsel ve Medya Optimizasyonu
Resimler, mobil uygulamalarda bellek tüketiminin en büyük nedenidir. React Native'in varsayılan `Image` bileşeni bazen yetersiz kalabilir.
### FastImage Kullanımı
`react-native-fast-image`, resim önbelleğe alma (caching) ve önceliklendirme konusunda standart bileşenden çok daha üstündür.
```javascript
import FastImage from 'react-native-fast-image';
```
## Animasyonlarda Native Driver Kullanımı
Animasyonlar JavaScript thread'ini bloke etmemelidir. `useNativeDriver: true` seçeneği, animasyon hesaplamalarını native tarafa aktarır.
```javascript
Animated.timing(fadeAnim, {
toValue: 1,
duration: 500,
useNativeDriver: true, // Kritik: Animasyonu native thread'e taşır
}).start();
```
## Bellek Yönetimi ve Memory Leak Önleme
Uygulama kapansa bile arka planda çalışan listener'lar veya interval'lar bellek sızıntısına yol açar. Bu durum uygulamanın zamanla yavaşlamasına ve çökmesine neden olur.
```javascript
useEffect(() => {
const subscription = AppState.addEventListener('change', handleState);
const timer = setInterval(() => {
console.log('Veri çekiliyor...');
}, 5000);
// Temizlik (Cleanup) işlemi
return () => {
subscription.remove();
clearInterval(timer);
};
}, []);
```
## Hermes Engine Aktivasyonu
Hermes, Facebook tarafından geliştirilen ve React Native için optimize edilmiş açık kaynaklı bir JavaScript motorudur. Uygulama açılış hızını (TTI) artırır ve APK boyutunu küçültür.
**android/app/build.gradle:**
```gradle
project.ext.react = [
enableHermes: true // Hermes'i aktif hale getirin
]
```
## Heavy Task Yönetimi: InteractionManager
Kullanıcı arayüzü geçişleri sırasında ağır işlemler yapmak takılmalara (jank) neden olur. `InteractionManager`, bu işlemleri animasyonlar bittikten sonraya erteler.
```javascript
import { InteractionManager } from 'react-native';
InteractionManager.runAfterInteractions(() => {
// Animasyon bittikten sonra çalışacak ağır hesaplama veya veri çekme
doExpensiveTask();
});
```
## Paket Boyutu ve Bundle Optimizasyonu
Uygulamanın ilk yükleme süresini düşürmek için paket boyutunu optimize etmek şarttır. Kullanılmayan kütüphaneler temizlenmeli ve `ProGuard` aktif edilmelidir.
### ProGuard Yapılandırması
Android'de kodun küçültülmesi ve obfuscation işlemi için `build.gradle` dosyasında şu ayar yapılmalıdır:
```gradle
def enableProguardInReleaseBuilds = true
```
## Sık Yapılan Hatalar
1. **Inline Fonksiyon Kullanımı:** Render içinde `onPress={() => doSomething()}` yazmak her seferinde yeni bir fonksiyon referansı oluşturur.
2. **Gereksiz Konsol Logları:** Production ortamında bırakılan `console.log` ifadeleri JavaScript thread'ini ciddi oranda yavaşlatır.
3. **Büyük JSON İşleme:** Çok büyük JSON verilerini JavaScript tarafında map etmek yerine, mümkünse bu işlemleri API tarafında veya native modüllerde yapın.
4. **Z-Index Karmaşası:** Çok fazla iç içe geçmiş view ve karmaşık z-index kullanımı GPU yükünü artırır.
## Sık Sorulan Sorular (SSS)
**1. React Native, Swift veya Kotlin kadar hızlı mıdır?**
Doğru optimize edildiğinde, kullanıcı aradaki farkı anlamayacak kadar yakındır. Ancak yoğun grafik işleme veya video düzenleme gibi durumlarda native diller hala avantajlıdır.
**2. FlatList neden yavaş çalışıyor?**
Genellikle `keyExtractor` eksikliği, çok büyük resimlerin liste içinde kullanılması veya `getItemLayout` parametresinin tanımlanmamış olması nedeniyle yavaşlık yaşanır.
**3. Hermes motoru her projede kullanılmalı mı?**
Evet, modern React Native projelerinde (0.64+) Hermes kullanılması şiddetle önerilir; bellek kullanımını %20-30 oranında azaltır.
**4. Redux performansı etkiler mi?**
Redux tek başına yavaş değildir. Ancak tüm state'i tek bir yerden güncellemek ve gereksiz bileşenleri `connect` ile bağlamak render sayısını artırabilir. `reselect` kütüphanesi ile selector optimizasyonu yapılmalıdır.
**5. Uygulama neden rastgele çöküyor?**
Genellikle bellek sızıntıları (memory leaks) veya native modüllerdeki asenkron hatalar buna neden olur. Flipper veya Xcode/Android Studio profiler araçları ile izlenmelidir.
## Özet
**React Native** performansı bir varış noktası değil, sürekli bir süreçtir. Köprü üzerindeki trafiği azaltmak, `Hermes` kullanmak, resimleri optimize etmek ve render döngülerini kontrol altında tutmak, uygulamanızın başarısı için kritiktir. Profesyonel bir uygulama geliştirmek için bu teknikleri standart bir pratik haline getirmelisiniz.