React Native uygulamalarında büyük listeleri kaydırırken takılma ve kasma sorunları sıkça yaşanır. FlatList, sonsuz kaydırma senaryolarında doğru yapılandırılmazsa bellek tüketimi artar ve kullanıcı deneyimi bozulur. Bu yazıda FlatList'in performansını artırmak için uygulayabileceğiniz somut adımları, yaygın hataları ve en iyi pratikleri ele alıyoruz.
FlatList'te Performansı Etkileyen Temel Faktörler
FlatList, yalnızca ekranda görünen öğeleri render ederek büyük veri kümelerini yönetir. Ancak her öğenin yüksekliği farklıysa, kaydırma sırasında sürekli hesaplama yapmak zorunda kalır. Ayrıca gereksiz yeniden render'lar, animasyonlar ve karmaşık alt bileşenler performansı düşürür.
getItemLayout ile Sabit Yükseklik Kullanımı
Eğer listedeki tüm öğeler aynı yüksekliğe sahipse, getItemLayout prop'unu tanımlayarak FlatList'e öğelerin konumunu önceden bildirebilirsiniz. Bu sayede kaydırma sırasında yükseklik hesaplaması yapılmaz, scroll çok daha akıcı olur.
const ITEM_HEIGHT = 80;
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
Dinamik yükseklik zorunluysa, içerik yüklendikten sonra ölçüm almak için onLayout kullanabilirsiniz, ancak bu ek maliyet getirir.
windowSize ve maxToRenderPerBatch ile Kontrollü Render
windowSize, ekranın üstünde ve altında render edilecek pencere boyutunu belirler. Varsayılan değer 21'dir (ekran yüksekliğinin 21 katı). Büyük listelerde bu değeri 10 veya daha düşük ayarlayarak bellek kullanımını azaltabilirsiniz. Aynı şekilde maxToRenderPerBatch ile her bir render partisinde kaç öğe render edileceğini sınırlayın.
Önemli: windowSize değerini çok düşük ayarlamak, kaydırma sırasında boşluk hissine neden olabilir. Test ederek optimum değeri bulun.
Key Extractor ve Bileşen Hafızası
Her öğeye benzersiz bir key vermek, React'in hangi öğelerin değiştiğini anlaması için kritiktir. keyExtractor prop'u ile index yerine veritabanı ID'si gibi stabil bir değer kullanın.
keyExtractor={(item) => item.id.toString()}
Ayrıca listedeki her bir öğeyi React.memo ile sarmalayarak, props değişmediği sürece yeniden render'ı önleyin.
const ListItem = React.memo(({ title }) => {
return {title} ;
});
Bu yaklaşım, özellikle state yönetiminde sık yapılan hataları da engellemeye yardımcı olur.
Sonsuz Kaydırma (Infinite Scroll) için onEndReached Kullanımı
Daha fazla veri yüklemek için onEndReached ve onEndReachedThreshold prop'larını kullanın. Threshold, listenin sonuna kaç piksel kala yeni veri yükleneceğini belirtir (0-1 arası oran). Örneğin 0.5, listenin yarısına gelindiğinde tetiklenir.
const loadMore = () => {
if (!isLoading && hasMore) {
setPage(prev => prev + 1);
}
};
}
/>
Burada dikkat edilmesi gereken, onEndReached'in birden fazla kez tetiklenmemesi için bir isLoading bayrağı kullanmaktır. Ayrıca tüm veri yüklendikten sonra hasMore kontrolü yapmayı unutmayın.
FlatList Performansını Kıran Yaygın Hatalar
- Inline fonksiyonlar: Her render'da yeni fonksiyon referansları oluşturulması, alt bileşenlerin gereksiz yeniden render almasına neden olur.
renderItemveonEndReachedgibi prop'larıuseCallbackile sabitleyin. - Gereksiz state güncellemeleri: Her kaydırmada state güncellemesi yapmak performansı düşürür. Örneğin scroll pozisyonunu state'te tutmak yerine
useRefkullanın. - Çok fazla nested component: Liste öğeleri ne kadar sade olursa o kadar iyidir. Karmaşık alt bileşenleri useEffect cleanup ile bellek sızıntılarına karşı koruyun.
Gelişmiş İpuçları: getItemLayout Olmadan Performans
Eğer dinamik yükseklik zorunluysa, her öğenin yüksekliğini ölçüp bir dizi olarak saklayabilirsiniz. Ancak bu yöntem karmaşıktır. Alternatif olarak CellRendererComponent ile özel bir render bileşeni oluşturup, yükseklik hesaplamasını başka bir thread'e taşıyabilirsiniz.
Bir diğer seçenek ise veri boyutunu küçültmektir. Örneğin, liste öğelerinde yalnızca görünen metni gösterin, detayları tıklamayla açın.
Sonsuz Kaydırmada Bellek Yönetimi
FlatList, görüntü alanı dışındaki öğeleri otomatik olarak temizler. Ancak resim gibi ağır kaynaklar hâlâ bellekte kalabilir. Resimleri Image bileşeniyle değil, FastImage gibi optimize kütüphanelerle yükleyin. Ayrıca useEffect ile temizlik yaparak bellek sızıntılarını önleme konusuna da dikkat edin.
Unutmayın: Performans optimizasyonu her zaman ölçümle başlar. React Native Debugger veya Flipper kullanarak hangi öğelerin kaç kez render edildiğini kontrol edin.
Alternatif Yaklaşımlar: No-Code ve Diğer Araçlar
Eğer uygulamanızın veri yönetimi kısmını hızlıca prototiplemek isterseniz, Airtable ve Bubble ile CRUD uygulaması gibi no-code çözümler de işinizi görebilir. Ancak büyük ölçekli projelerde FlatList'i doğru yapılandırmak vazgeçilmezdir.
Son Sözler
FlatList performansı, React Native uygulamalarının kullanıcı deneyimini doğrudan etkiler. getItemLayout, windowSize, React.memo ve useCallback gibi araçlarla infinite scroll'u akıcı hale getirebilirsiniz. Unutmayın: Her uygulama farklıdır; değerleri test ederek en uygun ayarları bulun. Bu optimizasyonları uygulayarak, binlerce öğeyi saniyede 60 kare hızında kaydırmak mümkündür.
Sık Sorulan Sorular
FlatList'te getItemLayout kullanmazsam ne olur?
Eğer getItemLayout tanımlanmazsa, FlatList öğelerin yüksekliğini dinamik olarak ölçmek zorunda kalır. Bu, özellikle büyük listelerde kaydırma sırasında gecikmelere ve takılmalara neden olabilir.
React Native'de sonsuz kaydırma için FlatList mi yoksa ScrollView mi kullanmalıyım?
ScrollView, tüm öğeleri tek seferde render ettiği için büyük listelerde bellek sorunları yaratır. FlatList, yalnızca ekrandakileri render ederek sonsuz kaydırma için çok daha uygundur.
windowSize değerini nasıl ayarlamalıyım?
Varsayılan 21'dir. Listede çok sayıda öğe varsa 10'a kadar düşürebilirsiniz. Ancak çok düşük ayarlamak, hızlı kaydırmalarda boş ekran görünmesine yol açabilir. Test ederek optimum değeri bulun.
FlatList'te her öğe aynı yükseklikte değilse performansı nasıl artırabilirim?
Her öğenin yüksekliğini ölçüp bir dizide saklayarak ve getItemLayout ile dinamik olarak iletebilirsiniz. Alternatif olarak, öğeleri sadeleştirip React.memo ve useCallback kullanarak gereksiz render'ları azaltın.
onEndReached neden birden fazla kez tetikleniyor?
Bu durum, isLoading kontrolü yapılmadığında oluşur. onEndReached içinde bir istek bayrağı kullanarak, veri yüklenirken yeni bir istek gönderilmesini engelleyin.



