Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить "windowing" / "virtualization"?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Windowing (віртуалізація)** - це техніка, за якої React рендерить лише видиму частину списку ("вікно") і кілька елементів навколо неї, а решта не створюється в DOM, доки до неї не прокрутиш. **Ключове:** менше DOM-вузлів означає меншу роботу браузера, менше пам'яті й менше reconciliation, тому список зі 100 000 елементів рендериться так само швидко, як і з десятками.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке *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 **завжди працює лише з невеликою частиною списку** (вікном), а не з усім деревом. --- ## Як це виглядає концептуально ```javascript +-----------------------------------------+ | (невидима частина, елементи не в DOM) | |-----------------------------------------| | item 95 | | item 96 | | item 97 ← початок вікна | | item 98 | | item 99 | | item 100 ← кінець вікна | |-----------------------------------------| | (невидима частина, елементи не в DOM) | +-----------------------------------------+ ``` При скролі вікно "повзе" вниз, React оновлює індекси елементів, але **не тримає весь список у пам'яті**. --- ## Приклад: без і з windowing ### Без віртуалізації ```javascript 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) ```javascript 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 | | Великий обсяг пам'яті | Малий обсяг пам'яті | | Складні ререндери | Мінімальні оновлення | | Проста реалізація | Потребує бібліотеки чи кастомної логіки | --- **Віртуалізація = "покажи лише те, що користувач реально бачить"** (і кілька рядків зверху/знизу для плавності).Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.