Що робить "windowing" / "virtualization"?
Що таке windowing / virtualization
Windowing (віртуалізація) - це техніка, при якій React рендерить лише видиму частину списку (тобто "вікно" = window) і кілька елементів навколо неї - а все інше не створюється в DOM, доки до нього не прокрутиш.
Приклад інтуїтивно:
Уяви, що у тебе є список із 10 000 елементів.
Без віртуалізації:
- React створює всі 10 000 елементів у DOM.
- Це десятки тисяч вузлів, CSS-стилів, layout-процесів, event-listeners.
- Рендер гальмує, пам'ять з'їдається, FPS падає.
З віртуалізацією:
- У DOM перебуває лише, наприклад, 30 елементів - ті, що видно на екрані + невеликий "запас" зверху і знизу.
- Коли користувач скролить - "вікно" зсувається, старі елементи видаляються з DOM, а нові додаються.
- Візуально створюється ілюзія, що список нескінченний.
Чому це швидко
- Менше DOM-вузлів → менше роботи браузера.
- Менше пам'яті → менше GC (збирання сміття).
- Менше React-рендерів → менше reconciliation.
- Обмежений перерахунок layout (reflow) і repaint.
Тобто React завжди працює лише з невеликою частиною списку (вікном), а не з усім деревом.
Як це виглядає концептуально
+-----------------------------------------+
| (невидима частина, елементи не в DOM) |
|-----------------------------------------|
| item 95 |
| item 96 |
| item 97 ← початок вікна |
| item 98 |
| item 99 |
| item 100 ← кінець вікна |
|-----------------------------------------|
| (невидима частина, елементи не в DOM) |
+-----------------------------------------+При скролі вікно "повзе" вниз, React оновлює індекси елементів, але не тримає весь список у пам'яті.
Приклад: без і з windowing
Без віртуалізації
function List({ items }) {
return (
<div>
{items.map((item, i) => (
<div key={i}>{item}</div>
))}
</div>
);
}→ Якщо items.length = 10_000,
React створить 10 000 <div> - браузеру погано.
З віртуалізацією (react-window)
import { FixedSizeList as List } from 'react-window';
function VirtualizedList({ items }) {
return (
<List
height={500} // висота видимої області
itemCount={items.length} // скільки всього елементів
itemSize={35} // висота одного елемента
width={300}
>
{({ index, style }) => (
<div style={style}>{items[index]}</div> // style позиціонує елемент
)}
</List>
);
}react-window сам рахує, які індекси зараз видно,
і малює лише їх (наприклад, зі 100 по 130).
"Вікно" = viewport списку
Браузер бачить лише частину контенту → віртуалізація створює ілюзію повного списку, а насправді відображається вікно (window) з кількох елементів.
Можна керувати:
overscanCount- скільки елементів зверху і знизу тримати "про запас";itemSizeабо динамічнаgetItemSize- висота елемента;VariableSizeList- для елементів різної висоти.
Які бібліотеки використовують windowing
| Бібліотека | Особливості |
|---|---|
| react-window | Легка, швидка, проста (FixedSize/VariableSize) |
| react-virtualized | Стара, потужна, підтримує таблиці, grid і autoSizer |
| @tanstack/react-virtual | Сучасна headless-реалізація, гнучка |
| FlatList (React Native) | Реалізація windowing для RN |
| VirtualScroller (Web API) | Нативний експериментальний аналог |
Коли використовувати virtualization
Обов'язково:
- при списках > 100 - 200 елементів, особливо якщо кожен елемент важкий;
- при таблицях з сотнями рядків;
- при "нескінченних стрічках" (чат, фід, каталоги).
Не потрібно:
- якщо елементів небагато (до ~50);
- якщо список часто додає/видаляє елементи посередині (перерахунок window дорожчий за вигоду);
- якщо важливий точний layout (наприклад, masonry, grid з динамічною шириною).
Підсумок
| Без віртуалізації | З віртуалізацією |
|---|---|
| Усі елементи в DOM | Лише видимі елементи |
| Повільно при 1000+ | Швидко навіть при 100 000 |
| Великий обсяг пам'яті | Малий обсяг пам'яті |
| Складні ререндери | Мінімальні оновлення |
| Проста реалізація | Потребує бібліотеки чи кастомної логіки |
Віртуалізація = "покажи лише те, що користувач реально бачить" (і кілька рядків зверху/знизу для плавності).
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.