Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як показати список на десятки тисяч рядків у React без гальмування?

Відрендерити 20 000 рядків таблиці - це 20 000 компонентів і сотні тисяч DOM-вузлів. Повільно все: перший рендер, кожне оновлення, прокрутка, пам'ять. memo тут не рятує - проблема в самій кількості.

Віртуалізація (windowing) - рендерити лише рядки, видимі на екрані, плюс невеликий запас. При прокрутці ті самі DOM-вузли отримують нові дані.

import { useVirtualizer } from '@tanstack/react-virtual';

function VacancyList({ items }) {
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 72,   // орієнтовна висота рядка
    overscan: 5,
  });

  return (
    <div ref={parentRef} style={{ height: 600, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
        {virtualizer.getVirtualItems().map((row) => (
          <div
            key={row.key}
            style={{ position: 'absolute', top: 0, transform: `translateY(${row.start}px)`, width: '100%' }}
          >
            <VacancyRow vacancy={items[row.index]} />
          </div>
        ))}
      </div>
    </div>
  );
}

У DOM постійно ~15 рядків замість 20 000, а висота контейнера дорівнює повній висоті списку - смуга прокрутки виглядає правильно.

Бібліотеки: TanStack Virtual (без готової розмітки, гнучкий), react-window, react-virtuoso (вміє динамічну висоту й «прилипання» до низу для чатів).

Складнощі, які треба врахувати:

  • рядки різної висоти - вимірювати після рендеру (measureElement) і оцінювати заздалегідь;
  • пошук браузера (Ctrl+F) не знайде текст рядків, яких немає в DOM;
  • доступність: зчитувачі екрана бачать лише відрендерені рядки - потрібні aria-rowcount/aria-rowindex;
  • збереження позиції прокрутки при поверненні на сторінку.

Альтернативи, які часто кращі:

  • пагінація чи «завантажити ще» - користувач рідко переглядає 20 000 рядків;
  • фільтри й пошук на сервері - показувати лише релевантне;
  • CSS content-visibility: auto - браузер пропускає розкладку й малювання позаекранних блоків, хоча DOM лишається повним. Простий виграш для довгих сторінок з помірною кількістю елементів.

Віртуалізація потрібна, коли весь набір справді має бути доступний прокруткою: логи, таблиці даних, великі чати.

Докладніше в документації: TanStack Virtual

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання