[Lv3] Virtual Scrolling: Merender Daftar Besar secara Efisien
Virtual scrolling menjaga ukuran DOM tetap kecil dengan merender hanya jendela yang terlihat ditambah buffer.
Situasi
Tabel besar dengan pembaruan yang sering dapat menghasilkan puluhan ribu node DOM, menyebabkan:
- Render awal yang lambat
- Stutter saat scroll
- Penggunaan memori yang tinggi
- Pembaruan yang mahal selama event real-time
Ide inti
Alih-alih merender semua baris, render hanya:
- Baris yang terlihat
- Overscan kecil sebelum dan sesudah viewport
Saat posisi scroll berubah, daur ulang kontainer baris dan perbarui jendela data yang ditampilkan.
Implementasi dasar (tinggi baris tetap)
const rowHeight = 48;
const viewportHeight = 480;
const visibleCount = Math.ceil(viewportHeight / rowHeight);
const startIndex = Math.floor(scrollTop / rowHeight);
const endIndex = startIndex + visibleCount + 6; // overscan
<div style={{ height: totalRows * rowHeight }}>
<div style={{ transform: `translateY(${startIndex * rowHeight}px)` }}>
{rows.slice(startIndex, endIndex).map(renderRow)}
</div>
</div>
Pertimbangan tinggi baris variabel
Untuk konten dinamis:
- Ukur tinggi baris secara lazy
- Pertahankan offset prefix-sum
- Gunakan binary search untuk memetakan
scrollTopke indeks
Jika tinggi baris sangat bervariasi, dukungan library biasanya lebih aman.
Jebakan interaksi dan perbaikan
- Jaga key yang stabil untuk mencegah remount yang tidak perlu
- Memoize komponen baris
- Debounce efek samping berat dari event scroll
- Pertahankan scroll anchor saat daftar diperbarui
Kapan menghindari virtual scroll
- Dataset kecil (kompleksitas mungkin tidak sebanding)
- Skenario yang memerlukan semua node DOM untuk operasi native browser
- Layout yang sangat tidak teratur dan sulit diukur
Ringkasan siap wawancara
Saya menerapkan virtual scrolling ketika jumlah baris tinggi dan biaya rendering mendominasi. Kuncinya adalah windowed rendering dengan overscan, key yang stabil, dan strategi pembaruan yang hati-hati agar scroll tetap lancar di bawah perubahan data yang sering.