Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorundan ve nasıl kurtulduğumdan bahsedeceğim. Müşterimden, 10.000'den fazla satırlık bir veriyi tabloda göstermem istendiğinde, ilk düşüncem "tabii, bir `map` döngüsüyle hallederiz" oldu. Ama işte o zaman kafayı yemiştim! Sayfa açılması 5 saniye sürüyor, scroll ederken tarayıcı resmen donuyordu. Tüm DOM elemanlarını render etmek, performans katili olmuştu.
Karşılaştığım Sorun ve Araştırma
Sorun şuydu: Kullanıcı aynı anda en fazla 20-30 satır görüyordu ama biz tüm 10.000 satırı DOM'a yüklüyor, tarayıcının hafızasını ve işlem gücünü boş yere tüketiyorduk. Bu klasik "listelemeyi" yaparken, scroll event'ini dinleyip sadece görünen kısmı render eden "Virtual Scrolling" (Sanal Kaydırma) tekniğini keşfettim. İlk etapta karmaşık geldi ama mantığını anlayınca aslında ne kadar zarif bir çözüm olduğunu gördüm.
Virtual Scrolling Mantığı Nasıl Çalışıyor?
Temel fikir basit: Bir container div'imiz var (viewport). İçinde, tüm listenin yüksekliğine eşit, ama içi büyük oranda boş bir div var (bu bize doğru scroll bar boyutunu veriyor). Scroll pozisyonuna göre, listenin hangi kısmının görünür alanda olduğunu hesaplıyoruz. Sadece o aralıktaki (örneğin, 20-40. elemanlar) elemanları alıp, uygun bir offset (kaydırma) ile container içine yerleştiriyoruz. Böylece DOM'da sürekli sadece 20-40 eleman bulunuyor.
React ve `react-window` ile Pratik Implementasyon
Her şeyi sıfırdan yazmak yerine, test edilmiş, güvenilir bir kütüphane kullanmak en iyisi. Ben `react-window` kütüphanesini tercih ettim. Kurulumdan sonra, eski kodumla yeni kodum arasındaki fark inanılmazdı.
İşte eski, performanssız yöntemim:
Ve işte `react-window` ile gelen mucize:
Bu kodu yazıp çalıştırdığım an, sayfanın anında açılması ve scroll'ın tereyağı gibi kayması beni resmen mutluluk gözyaşlarına boğdu. `react-window`, scroll pozisyonuna göre hangi `Row` component'lerinin render edileceğini otomatik hesaplıyor ve yönetiyor.
Elde Ettiğim Performans Kazancı
Performans analiz araçlarıyla (React Profiler, Chrome DevTools Performance tab) yaptığım ölçümlerde:
- İlk Render Süresi: ~5 saniyeden ~150 milisaniyeye düştü.
- Hafıza Kullanımı: DOM Node sayısı 10.000'den ~40'a düştü.
- Scroll Performansı: FPS (saniyedeki kare sayısı) 60'ın altına hiç düşmedi, kesintisiz bir deneyim.
Sonuç olarak, büyük veri setleriyle çalışırken tüm veriyi DOM'a yüklemek yerine virtual scrolling kullanmak, kullanıcı deneyimini kurtaran bir olmazsa olmaz haline geldi. Siz de benzer bir sorunla karşılaştınız mı? Vue veya vanilla JS için kullandığınız farklı virtual scroll kütüphaneleri veya kendi yöntemleriniz var mı? Yorumlarda paylaşalım!
Sorun şuydu: Kullanıcı aynı anda en fazla 20-30 satır görüyordu ama biz tüm 10.000 satırı DOM'a yüklüyor, tarayıcının hafızasını ve işlem gücünü boş yere tüketiyorduk. Bu klasik "listelemeyi" yaparken, scroll event'ini dinleyip sadece görünen kısmı render eden "Virtual Scrolling" (Sanal Kaydırma) tekniğini keşfettim. İlk etapta karmaşık geldi ama mantığını anlayınca aslında ne kadar zarif bir çözüm olduğunu gördüm.
Temel fikir basit: Bir container div'imiz var (viewport). İçinde, tüm listenin yüksekliğine eşit, ama içi büyük oranda boş bir div var (bu bize doğru scroll bar boyutunu veriyor). Scroll pozisyonuna göre, listenin hangi kısmının görünür alanda olduğunu hesaplıyoruz. Sadece o aralıktaki (örneğin, 20-40. elemanlar) elemanları alıp, uygun bir offset (kaydırma) ile container içine yerleştiriyoruz. Böylece DOM'da sürekli sadece 20-40 eleman bulunuyor.
Her şeyi sıfırdan yazmak yerine, test edilmiş, güvenilir bir kütüphane kullanmak en iyisi. Ben `react-window` kütüphanesini tercih ettim. Kurulumdan sonra, eski kodumla yeni kodum arasındaki fark inanılmazdı.
İşte eski, performanssız yöntemim:
JavaScript:
function EskiTablom({ veriler }) {
return (
<div className="table-container">
{veriler.map((veri, index) => (
<div key={index} className="table-row">
{veri.isim} - {veri.email} {/ 10.000 kez render! /}
</div>
))}
</div>
);
}
Ve işte `react-window` ile gelen mucize:
JavaScript:
import { FixedSizeList as List } from 'react-window';
function YeniTablom({ veriler }) {
// Her bir satırı nasıl render edeceğimizi tanımlıyoruz.
const Row = ({ index, style }) => {
const veri = veriler[index];
return (
<div style={style} className="table-row"> {/ style, pozisyonu otomatik ayarlıyor /}
{veri.isim} - {veri.email}
</div>
);
};
return (
<List
height={500} // Viewport yüksekliği
itemCount={veriler.length} // Toplam eleman sayısı
itemSize={35} // Her bir satırın yüksekliği (px)
width="100%"
>
{Row} // Render fonksiyonunu veriyoruz
</List>
);
}
Bu kodu yazıp çalıştırdığım an, sayfanın anında açılması ve scroll'ın tereyağı gibi kayması beni resmen mutluluk gözyaşlarına boğdu. `react-window`, scroll pozisyonuna göre hangi `Row` component'lerinin render edileceğini otomatik hesaplıyor ve yönetiyor.
Performans analiz araçlarıyla (React Profiler, Chrome DevTools Performance tab) yaptığım ölçümlerde:
- İlk Render Süresi: ~5 saniyeden ~150 milisaniyeye düştü.
- Hafıza Kullanımı: DOM Node sayısı 10.000'den ~40'a düştü.
- Scroll Performansı: FPS (saniyedeki kare sayısı) 60'ın altına hiç düşmedi, kesintisiz bir deneyim.
Sonuç olarak, büyük veri setleriyle çalışırken tüm veriyi DOM'a yüklemek yerine virtual scrolling kullanmak, kullanıcı deneyimini kurtaran bir olmazsa olmaz haline geldi. Siz de benzer bir sorunla karşılaştınız mı? Vue veya vanilla JS için kullandığınız farklı virtual scroll kütüphaneleri veya kendi yöntemleriniz var mı? Yorumlarda paylaşalım!