React Native uygulamalarında büyük listeleri kaydırırken takılma (jank) veya yavaşlama yaşıyorsanız, FlatList bileşenini doğru yapılandırmamış olabilirsiniz. FlatList, varsayılan ayarlarla binlerce öğeyi işleyebilir ancak gerçek performansı optimize edilmiş parametrelerle elde edersiniz. Bu yazıda, getItemLayout, keyExtractor ve PureComponent kullanarak FlatList performansını nasıl artıracağınızı adım adım göreceksiniz.
1. keyExtractor ile Benzersiz Anahtar Sağlayın
FlatList'teki her öğe için benzersiz ve sabit bir anahtar (key) atamak, React Native'in hangi öğelerin yeniden render edilmesi gerektiğini doğru şekilde belirlemesini sağlar. Varsayılan olarak FlatList, key prop'unu kullanır ancak keyExtractor fonksiyonu ile veri nesnelerinden anahtar üretebilirsiniz.
- Pratik ipucu:
keyExtractorfonksiyonundaitem.id.toString()gibi benzersiz bir değer döndürün. Dizini (index) kullanmaktan kaçının çünkü liste sırası değiştiğinde performans sorunlarına yol açabilir. - Örnek:
keyExtractor={(item) => item.id}
2. getItemLayout ile Sabit Yükseklik Kullanın
Eğer listenizdeki tüm öğeler aynı yüksekliğe sahipse, getItemLayout prop'unu tanımlayarak FlatList'e öğelerin konumunu önceden bildirin. Bu sayede hesaplama maliyeti düşer ve kaydırma sırasında daha az işlem yapılır.
- Pratik ipucu: Öğe yüksekliği sabitse
getItemLayoutkullanın. Dinamik yüksekliklerde iseonLayoutile ölçüm yapmanız gerekir. - Örnek:
getItemLayout={(data, index) => ( { length: 80, offset: 80 * index, index } )}
3. PureComponent veya React.memo ile Gereksiz Render'ları Engelle
FlatList'teki her öğe bir bileşense, bu bileşenin React.PureComponent olması veya React.memo ile sarılması, prop'lar değişmediğinde yeniden render'ı engeller. Özellikle büyük listelerde bu optimizasyon büyük fark yaratır.
- Pratik ipucu: Öğe bileşeninizi
React.memoile sarmalayın ve gereksiz prop'ları azaltın. Eğer fonksiyon prop'ları kullanıyorsanız,useCallbackile sabitleyin. Bu konuda daha fazla bilgi için React Performans Optimizasyonu: useMemo vs useCallback vs React.memo yazısını inceleyebilirsiniz.
4. windowSize ve maxToRenderPerBatch Ayarları
FlatList, görünür alanın dışındaki öğeleri render etmez ancak windowSize ve maxToRenderPerBatch parametreleri ile bu davranışı kontrol edebilirsiniz.
- Pratik ipucu:
windowSizevarsayılan değeri 21'dir (10 ekran yukarı, 10 ekran aşağı, 1 ekran görünür). Düşük değerler (ör. 5) bellek kullanımını azaltır ancak kaydırma sırasında boş alan görünmesine neden olabilir. Deneyerek en uygun değeri bulun. maxToRenderPerBatchvarsayılan 10'dur. Bu değeri artırmak (ör. 20) başlangıçta daha fazla öğe render edilmesini sağlar, ancak kaydırma sırasında daha az batch çalışır.
5. removeClippedSubviews ve initialNumToRender
removeClippedSubviews=true ayarı, görünür alanın dışındaki öğelerin native görünümlerini kaldırarak bellek tasarrufu sağlar. Ancak bazı durumlarda kaydırma sırasında yanıp sönmelere yol açabilir. initialNumToRender ise ilk render'da kaç öğe gösterileceğini belirler; varsayılan 10'dur. Ekran boyutuna göre bu değeri artırabilirsiniz.
- Öneri: Eğer listeniz çok büyükse (1000+ öğe),
removeClippedSubviewskullanın. Aksi halde performans kazancı sınırlı olabilir.
6. Kontrol Listesi: FlatList Performans Optimizasyonu
Aşağıdaki kontrol listesini uygulayarak FlatList'inizi optimize edebilirsiniz:
- keyExtractor ile benzersiz anahtar atandı mı?
- Sabit yükseklik varsa getItemLayout tanımlandı mı?
- Öğe bileşenleri PureComponent veya React.memo ile sarıldı mı?
- windowSize ve maxToRenderPerBatch optimize edildi mi?
- Gereksiz state ve prop'lar kaldırıldı mı?
- Listede görsel değişiklikler (ör. animasyon) varsa
useNativeDriverkullanıldı mı? -
removeClippedSubviewstest edildi mi? - Liste verisi
useMemoile memoize edildi mi? Bu konuda useRef Hook'unun Derinlemesine Kullanımı yazısında referans kararlılığı hakkında ipuçları bulabilirsiniz.
Sık Yapılan Hatalar
- Her öğede inline fonksiyon kullanmak:
renderItemiçinde arrow fonksiyon tanımlamak her render'da yeni bir fonksiyon oluşturur. Bunun yerine fonksiyonu dışarıda tanımlayın. - keyExtractor olarak index kullanmak: Liste sırası değiştiğinde (ekleme/silme) tüm öğelerin yeniden render edilmesine neden olur.
- Büyük veri kümelerinde tüm veriyi state'te tutmak: Liste çok büyükse sayfalama (pagination) veya lazy loading kullanın.
Sonuç
FlatList performansını artırmak için getItemLayout, keyExtractor ve PureComponent/React.memo gibi araçları doğru kullanmak yeterlidir. Yukarıdaki kontrol listesini uygulayarak listelerinizi pürüzsüz hale getirebilirsiniz. Unutmayın, her optimizasyonun bir maliyeti vardır; bu nedenle profilleme yaparak hangi adımların en büyük kazancı sağladığını test edin.
Sık Sorulan Sorular
FlatList'te getItemLayout kullanmak zorunlu mu?
Zorunlu değildir ancak sabit yükseklikli öğelerde performansı önemli ölçüde artırır. Eğer öğe yükseklikleri dinamikse getItemLayout kullanılamaz, onLayout ile ölçüm yapılmalıdır.
keyExtractor olarak index kullanmanın dezavantajı nedir?
Index kullanmak, liste sırası değiştiğinde (ör. öğe ekleme/silme) React Native'in öğeleri yanlış eşlemesine ve gereksiz yeniden render'lara yol açar. Benzersiz bir id kullanmak her zaman daha iyidir.
PureComponent ile React.memo arasında ne fark var?
PureComponent sınıf bileşenleri için, React.memo ise fonksiyonel bileşenler için kullanılır. Her ikisi de prop'ları yüzeysel olarak karşılaştırarak gereksiz render'ları engeller.
windowSize değerini ne kadar düşürebilirim?
windowSize değerini düşürmek bellek kullanımını azaltır ancak kaydırma sırasında boş alan görünmesine neden olabilir. Genellikle 5-10 arası değerler iyi bir dengedir, ancak uygulamanıza göre test ederek bulmalısınız.
FlatList'te animasyon kullanırken performans nasıl artırılır?
Animasyonlarda useNativeDriver: true kullanarak animasyonları native thread'de çalıştırın. Ayrıca Animated.View gibi bileşenleri PureComponent ile sararak gereksiz render'ları önleyin.






