Thứ tự chẩn đoán:
1. Đo trước — Profiler cho biết chậm ở render React hay ở layout/paint của trình duyệt. 10.000 node DOM thường chậm ở phần trình duyệt, memo hoá không cứu được.
2. Giảm số dòng thật sự cần — phân trang, cuộn vô hạn, lọc phía server. Rẻ nhất và thường đủ.
3. Virtualization (windowing) — chỉ render các dòng trong viewport cộng một vùng đệm; số node DOM giữ ở mức vài chục bất kể dữ liệu lớn cỡ nào. Thư viện hay dùng: react-window, @tanstack/react-virtual.
4. Song song: memo hoá row component để scroll không render lại các dòng còn nằm trong window.
Cạm bẫy của virtualization:
- Chiều cao động — nội dung tự co giãn khiến vị trí tính sai, phải đo động (ResizeObserver) hoặc chấp nhận nhảy scroll.
- Ctrl+F và SEO — nội dung ngoài viewport không tồn tại trong DOM, không tìm bằng trình duyệt được, không index được.
- Accessibility — screen reader và phím Tab cần aria-rowcount/aria-rowindex để hiểu tổng số dòng.
- Sticky header, colspan, drag-to-reorder đều khó hơn nhiều khi row nằm ở vị trí absolute.
Nếu bảng chỉ vài trăm dòng, virtualization thường là phức tạp thừa — cân nhắc content-visibility: auto của CSS trước.