Langsung ke konten utama

[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 scrollTop ke 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.