React Native uygulamalarında uzun listeleri FlatList ile render ederken karşılaşılan en yaygın performans sorunları, gereksiz yeniden render'lar ve artan bellek kullanımıdır. FlatList'in sanallaştırma mekanizmasını doğru yapılandırarak hem kaydırma akıcılığını hem de bellek verimliliğini büyük ölçüde artırabilirsiniz. Bu yazıda FlatList'in sanallaştırma özelliklerini nasıl optimize edeceğinizi ve bellek yönetimi için uygulayabileceğiniz somut ipuçlarını adım adım inceleyeceğiz.
FlatList Sanallaştırma Nasıl Çalışır?
FlatList, yalnızca ekranda görünen ve yakın çevresindeki öğeleri render ederek büyük veri kümelerinde bile yüksek performans sağlar. Varsayılan olarak windowSize değeri 21'dir (ekran yüksekliğinin 10 katı kadar öğe öncesi ve sonrası). Ancak bu değer her zaman optimum değildir. Aşağıdaki ayarlarla sanallaştırmayı ince ayar yapabilirsiniz:
- getItemLayout: Her bir öğenin sabit yüksekliği varsa bu prop’u tanımlayarak FlatList'in ölçüm hesaplamalarını atlamasını sağlayın. Bu, kaydırma sırasında hesaplama yükünü azaltır.
- windowSize: Varsayılan 21 yerine, listenizdeki öğe sayısına ve kullanıcı kaydırma hızına göre daha düşük bir değer (örneğin 5-10) belirleyin. Bu, bellekte tutulan öğe sayısını azaltır.
- removeClippedSubviews: true olarak ayarlandığında, ekran dışındaki öğelerin native görünümleri kaldırılır. Bu, bellek kullanımını düşürür ancak kaydırma sırasında yeniden oluşturma maliyeti olabilir. Dengeli kullanım için önerilir.
- maxToRenderPerBatch ve updateBatchesPerPeriod: Her bir toplu işlemde render edilecek maksimum öğe sayısını ve güncelleme sıklığını kontrol edin. Varsayılan değerler genellikle yeterlidir; ancak çok hızlı kaydırmalarda düşük ayarlar takılmalara neden olabilir.
Bellek Yönetimi İçin İpuçları
1. Resim ve Medya Önbellekleme
Liste öğelerinde resim kullanıyorsanız, fast-image gibi kütüphanelerle önbellekleme yapın. Ayrıca resim boyutlarını liste öğesiyle uyumlu hale getirin ve gereksiz büyük resimlerden kaçının. Bu, hem bellek hem de işlemci yükünü azaltır.
2. useCallback ve useMemo ile Gereksiz Render'ları Engelleme
FlatList'in renderItem fonksiyonunu ve alt bileşenleri React.useCallback veya React.memo ile sarmalayarak her kaydırmada yeniden oluşturulmasını engelleyin. Özellikle liste öğelerinde karmaşık hesaplamalar varsa useMemo kullanarak değerleri önbelleğe alın.
3. State Yönetimini Optimize Edin
Liste verilerini sık sık güncelliyorsanız, tüm listeyi değil yalnızca değişen öğeleri güncelleyin. Bunun için React.memo ile birlikte keyExtractor prop'una benzersiz ve stabil bir anahtar verin. Ayrıca React useReducer Hook ile Karmaşık State Yönetimi yöntemlerini kullanarak state güncellemelerini daha verimli hale getirebilirsiniz. Detaylı bilgi için React useReducer Hook ile Karmaşık State Yönetimi: Pratik İpuçları ve Kontrol Listesi yazımıza göz atın.
4. Asenkron İşlemleri Yönetin
Liste içinde yapılan ağ istekleri veya veritabanı işlemleri, kaydırma performansını olumsuz etkileyebilir. İstekleri iptal edilebilir yapın ve tamamlandığında state'i güncelleyin. JavaScript Promise ve Async/Await ile Hata Yönetimi konusundaki pratik ipuçları sayesinde asenkron akışınızı daha sağlam hale getirebilirsiniz.
Kontrol Listesi
- getItemLayout tanımlandı mı? (Sabit yükseklik varsa)
- windowSize değeri optimize edildi mi? (Düşük değer dene)
- removeClippedSubviews true ayarlandı mı?
- keyExtractor ile benzersiz ve stabil anahtar kullanılıyor mu?
- renderItem bileşeni React.memo ile sarıldı mı?
- Resimler önbelleğe alınıyor ve boyutlandırılıyor mu?
- State güncellemelerinde yalnızca değişen öğeler mi güncelleniyor?
- Asenkron işlemler iptal edilebilir ve hata yönetimi yapılıyor mu?
- Bellek profili (Heap) düzenli olarak kontrol ediliyor mu?
FlatList vs ScrollView: Ne Zaman Hangisi?
Binlerce öğe için FlatList, az sayıda (örneğin 20'den az) öğe için ScrollView daha uygundur. Ayrıca Lazy Loading prensipleriyle benzer şekilde, yalnızca ihtiyaç duyulan veriyi yükleyin. React'te Lazy Loading ve Code Splitting makalemizde bu konseptin web versiyonunu bulabilirsiniz; React Native'de de aynı mantık geçerlidir.
Sık Yapılan Hatalar
- Her öğede fonksiyon tanımlamak: renderItem içinde fonksiyon oluşturmayın; dışarıda tanımlayın.
- Inverted listelerde windowSize ayarını unutmak: Ters liste (sohbet uygulamaları gibi) kullanıyorsanız windowSize'ı artırmanız gerekebilir.
- Ölçüm yapmadan optimize etmek: Her zaman profiler ile performansı ölçün; varsayılan değerler bazen yeterli olabilir.
Bu ipuçlarını uygulayarak React Native uygulamanızdaki liste performansını önemli ölçüde artırabilirsiniz. Unutmayın, her proje farklıdır; bu nedenle ayarları kendi kullanıcı akışınıza göre test edin.
Sık Sorulan Sorular
FlatList'te windowSize değerini ne kadar küçük ayarlayabilirim?
windowSize değerini 1'e kadar düşürebilirsiniz, ancak bu çok agresif sanallaştırmaya neden olur ve hızlı kaydırmalarda boş alanlar görünebilir. Genellikle 5-10 arası iyi bir dengedir.
getItemLayout kullanmazsam ne olur?
FlatList her öğenin yüksekliğini ölçmek için ek hesaplama yapar. Bu, özellikle büyük listelerde kaydırma sırasında takılmalara yol açabilir. Sabit yükseklik varsa getItemLayout mutlaka tanımlayın.
React.memo ile FlatList performansı artar mı?
Evet, renderItem içinde kullanılan bileşenleri React.memo ile sarmalamak, yalnızca değişen öğelerin yeniden render edilmesini sağlayarak performansı artırır.
removeClippedSubviews her zaman açık olmalı mı?
Genellikle evet, çünkü ekran dışı öğeleri kaldırarak bellek kullanımını azaltır. Ancak kaydırma sırasında yeniden oluşturma maliyeti olabilir; test ederek karar verin.






