Виртуализация — это техника оптимизации рендеринга больших списков элементов в пользовательском интерфейсе. В обычных условиях React рендерит все элементы списка в DOM, что при сотнях или тысячах элементов приводит к значительным проблемам с производительностью. React Aria предоставляет высокоуровневые хуки и утилиты для безопасной и эффективной виртуализации, сохраняя доступность интерфейсов.
useVirtualizerКлючевым инструментом для виртуализации в React Aria является хук
useVirtualizer. Он обеспечивает отслеживание видимых
элементов, вычисление размеров контейнера и элементов, а также
управление прокруткой.
import { useVirtualizer } from '@react-aria/virtualizer';
Основные параметры хука:
count — общее количество элементов в
списке.getScrollElement — функция,
возвращающая контейнер, на котором осуществляется прокрутка.estimateSize — функция, возвращающая
предполагаемую высоту или ширину элемента.overscan — количество элементов до и
после видимой области, которые будут рендериться для плавного
скроллинга.Пример базового использования:
function VirtualList({ items }) {
const scrollRef = useRef(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 50,
overscan: 5
});
return (
<div ref={scrollRef} style={{ height: 400, overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
{virtualizer.getVirtualItems().map(virtualRow => (
<div
key={virtualRow.index}
style={{
position: 'absolute',
top: virtualRow.start,
height: virtualRow.size,
width: '100%'
}}
>
{items[virtualRow.index]}
</div>
))}
</div>
</div>
);
}
React Aria поддерживает как фиксированные, так и динамические размеры
элементов. Для динамических размеров используется функция
measureElement, которая позволяет виртуализатору точно
отслеживать размер каждого элемента после рендера.
const measureElement = (el) => el.getBoundingClientRect().height;
При изменении размеров элементов хук автоматически обновляет позиции и смещения всех виртуализированных элементов.
Помимо вертикальных списков, React Aria поддерживает горизонтальные прокрутки. Для этого достаточно передать параметр ориентации:
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 120,
orientation: 'horizontal',
overscan: 3
});
Стилизация контейнера изменяется соответствующим образом: вместо высоты фиксируется ширина и прокрутка осуществляется по оси X.
Виртуализация тесно интегрируется с другими компонентами React Aria,
например ListBox, Menu, Table.
Это позволяет поддерживать полную доступность элементов:
Пример интеграции с ListBox:
import { useListBox, useListBoxSection } from '@react-aria/listbox';
function VirtualizedListBox({ items, listBoxProps }) {
const scrollRef = useRef(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 40,
overscan: 5
});
return (
<div ref={scrollRef} style={{ height: 300, overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
{virtualizer.getVirtualItems().map(virtualRow => (
<div
key={virtualRow.index}
style={{
position: 'absolute',
top: virtualRow.start,
height: virtualRow.size,
width: '100%'
}}
>
{items[virtualRow.index].name}
</div>
))}
</div>
</div>
);
}
React Aria можно сочетать с подгрузкой данных по мере скроллинга. Для
этого используется событие onScroll на контейнере и
проверка индекса последнего виртуализированного элемента:
const lastItem = virtualizer.getVirtualItems().slice(-1)[0];
if (lastItem.index >= items.length - 1) {
loadMoreItems();
}
Это позволяет создавать списки с тысячами элементов без значительного влияния на производительность.
Виртуализация в React Aria позволяет:
Эффективная виртуализация становится фундаментом для создания масштабируемых и отзывчивых интерфейсов, особенно при работе с большими объемами данных.