React İle Performans Odaklı Liste Sanallaştırma Nasıl Yapılır?

React İle Performans Odaklı Liste Sanallaştırma Nasıl Yapılır?
React İle Performans Odaklı Liste Sanallaştırma Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Uygulamaya başlamadan önce sisteminizde Node.js (v20 veya üzeri) ve güncel bir React projesinin kurulu olması gerekir. Sanallaştırma işlemleri için manuel bir "windowing" mekanizması yazmak yerine, endüstri standardı olan react-window kütüphanesini kullanacağız.

Projenize gerekli bağımlılıkları yüklemek için terminalinizde aşağıdaki komutu çalıştırın:

npm install react-window

Bu kütüphane, yüksek performanslı liste oluşturma işlemleri için optimize edilmiş bileşenler sunar. Kurulum sonrası, projenizin package.json dosyasında bağımlılığın eklendiğini doğrulayın.

Adım Adım Liste Sanallaştırma Mantığı

Sanallaştırmanın temel mantığı, kaydırma (scroll) olaylarını dinleyerek, kullanıcının gördüğü pencereyi dinamik olarak güncellemektir. Aşağıdaki örnekte, sanallaştırma kullanmadan yapılan standart bir listenin neden performans kaybına yol açtığını ve basit bir yapı ile nasıl iyileştirileceğini göreceğiz.

// Standart ve performanssız liste örneği
const LargeList = ({ items }) => {
  return (
    
    {items.map((item, index) => (
  • {item.name}
  • ))}
); };

Yukarıdaki kod, 10.000 öğe olduğunda 10.000 adet li etiketini DOM'a ekler. Bu, bellek tüketimini artırır ve özellikle düşük donanımlı cihazlarda "donma" hissine neden olur.

React-Window ile Temel Uygulama

Şimdi, react-window kullanarak sabit yükseklikteki satırlardan oluşan bir listeyi sanallaştıralım. FixedSizeList bileşeni, her satırın yüksekliğinin aynı olduğu senaryolar için en hızlı çözümdür.

import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => (
  
Satır {index}
); const App = () => ( {Row} );

Burada height ve width, listenin kapladığı alanı; itemSize ise her bir satırın piksel cinsinden yüksekliğini belirler. Row bileşeni, kütüphane tarafından otomatik olarak sağlanan style nesnesini alarak satırın konumlandırılmasını sağlar.

Kritik Uyarı: Sanallaştırılmış listelerde style prop'unu satır bileşenine uygulamayı unutmayın. Aksi takdirde, öğeler üst üste binecek ve kaydırma işlemi düzgün çalışmayacaktır.

Performans Karşılaştırması

Aşağıdaki tablo, standart render yöntemi ile sanallaştırma yönteminin performans farklarını özetlemektedir.

Özellik Standart Liste Sanallaştırılmış Liste
Bellek Kullanımı Çok Yüksek Çok Düşük
DOM Düğüm Sayısı Veri Seti Boyutuyla Eşit Görünür Alan + Tampon
İlklendirme Hızı Yavaş Anlık

Dinamik Yükseklikli Satırlar İçin Sanallaştırma

Bazı durumlarda satır içerikleri değişken uzunluktadır. Bu durumda FixedSizeList yerine VariableSizeList kullanmanız gerekir. Bu yöntem, her satırın yüksekliğini ölçerek hesaplar.

import { VariableSizeList as List } from 'react-window';

const getItemSize = index => (index % 2 === 0 ? 50 : 100);

const App = () => (
  
    {({ index, style }) => 
Satır {index}
} );

itemSize özelliğine bir fonksiyon atayarak, her satırın yüksekliğini indeksine göre dinamik olarak belirleyebilirsiniz. Bu, kullanıcı deneyimini bozmadan esnek içerik sunmanıza olanak tanır.

Yaygın Hatalar ve Debug İpuçları

Liste sanallaştırma sırasında karşılaşılan en yaygın hata, kaydırma çubuğunun (scrollbar) yanlış hesaplanmasıdır. Genellikle liste bileşeninin kapsayıcı (container) boyutlarının CSS ile doğru verilmemesinden kaynaklanır.

  • Hata: Satırların boş görünmesi. Çözüm: style prop'unun satıra uygulandığından emin olun.
  • Hata: Kaydırma performansının düşmesi. Çözüm: Satır bileşenlerini React.memo ile sarmalayarak gereksiz yeniden render işlemlerini engelleyin.
  • Hata: Liste boyutlarının yanlış hesaplanması. Çözüm: width ve height değerlerini sayısal olarak (piksel) verin, yüzde (%) kullanıyorsanız react-window-size gibi yardımcı kütüphanelerden destek alın.
Güvenlik Sorumluluk Reddi: Bu rehberdeki kod örnekleri performans optimizasyonu odaklıdır. Uygulamanızda kullanıcıdan gelen verileri listelerken XSS (Cross-Site Scripting) saldırılarına karşı verileri her zaman sanitize edin ve güvenli bir şekilde render edin.

Sıkça Sorulan Sorular

Sanallaştırma SEO'yu etkiler mi?

Evet, arama motorları sadece DOM'da olan içeriği görür. Eğer liste içeriğinizin SEO için kritik önemi varsa, sanallaştırma yerine "Lazy Loading" veya "Pagination" (sayfalandırma) yöntemlerini tercih etmelisiniz.

Çok büyük veri setlerinde ne yapmalıyım?

Sadece sanallaştırma yeterli olmayabilir. Veriyi parça parça çekmek (Infinite Scroll) ve sanallaştırmayı bu veri akışıyla birleştirmek en iyi pratiktir.

Mobil cihazlarda sanallaştırma farklı mı çalışır?

Temel mantık aynıdır ancak dokunmatik kaydırma (touch scrolling) olayları tarayıcı tarafından farklı işlenir. react-window bu konuda oldukça başarılıdır.

Neden kendi çözümümü yazmıyorum?

Kendi sanallaştırma çözümünüzü yazmak; uç durumları (edge cases), kaydırma ivmesini ve tarayıcı uyumluluğunu yönetmek açısından oldukça zordur. Hazır kütüphaneler bu konuda binlerce testten geçmiştir.

React 19/20 ile uyumlu mu?

Evet, bu kütüphaneler React'in modern sürümleriyle tam uyumludur ve Concurrent Mode ile sorunsuz çalışır.

Sanallaştırılmış Listelerde İleri Düzey Optimizasyon: "Overscan" ve "Memoization"

Sanallaştırma kütüphaneleri varsayılan olarak belirli bir "overscan" (görünür alanın dışındaki öğelerin önceden render edilmesi) değeriyle gelir. Bu değer, kullanıcının hızlı kaydırma yaptığı durumlarda listenin boş görünmesini engeller. Ancak, karmaşık bileşenler render ediyorsanız, bu değerin doğru ayarlanması performansı doğrudan etkiler.

Ayrıca, liste öğelerinizin gereksiz yere yeniden render edilmesini önlemek için React.memo kullanmak zorunludur. Eğer liste öğeniz props olarak bir fonksiyon veya nesne alıyorsa, useCallback ve useMemo kullanarak bu referansların sabit kalmasını sağlamalısınız.

import React, { memo, useCallback } from 'react';
import { FixedSizeList as List } from 'react-window';

const Row = memo(({ data, index, style }) => {
  const item = data[index];
  return (
    
{item.name}
); }); const MyList = ({ items }) => { const itemKey = useCallback((index, data) => data[index].id, []); return ( {Row} ); };

Alternatif: TanStack Virtual ile Modern Yaklaşım

react-window oldukça popüler olsa da, daha esnek ve modern bir API arıyorsanız @tanstack/react-virtual kütüphanesi mükemmel bir alternatiftir. Bu kütüphane, "headless" yapısı sayesinde DOM yapısı üzerinde tam kontrol sağlar ve özellikle karmaşık düzenlerde (grid, yatay kaydırma vb.) daha başarılı sonuçlar verir.

TanStack Virtual Kullanım Avantajları

  • Headless Tasarım: HTML yapısını tamamen siz belirlersiniz, kütüphane sadece hesaplamaları yapar.
  • Dinamik Boyutlandırma: Ölçüleri önceden bilinemeyen içerikler için daha kararlı bir yapı sunar.
  • TypeScript Desteği: Tip güvenliği konusunda çok daha gelişmiş bir geliştirici deneyimi sağlar.
import { useVirtualizer } from '@tanstack/react-virtual';
import { useRef } from 'react';

function VirtualList({ items }) {
  const parentRef = useRef();
  const rowVirtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 35,
  });

  return (
    
{rowVirtualizer.getVirtualItems().map((virtualRow) => (
{items[virtualRow.index].name}
))}
); }

Bu yaklaşım, özellikle position: absolute ve transform kullanarak kaydırma performansını maksimize eder. Tarayıcı, GPU hızlandırmasını kullanarak bu dönüşümleri çok daha akıcı bir şekilde işler.

Sonuç

React ile performans odaklı liste sanallaştırma, büyük ölçekli uygulamaların olmazsa olmaz bir parçasıdır. react-window kullanarak DOM yükünü hafifletmek, uygulamanızın kullanıcı deneyimini doğrudan iyileştirecektir. Unutmayın ki, en iyi performans, gereksiz render işlemlerinden kaçınmakla başlar. Bir sonraki adım olarak, listenize "Infinite Scroll" (sonsuz kaydırma) özelliğini entegre ederek verileri arka planda asenkron olarak yüklemeyi deneyebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Mert Demir

Teknik beceriler ve bakım onarım rehberleri konusunda deneyimli bir editörüm. Okuyucularıma günlük hayatta tasarruf sağlayacak ipuçları sunuyorum.

Yorumlar (0)

Yorum Yaz