Haunted — это библиотека для создания реактивных веб-компонентов на основе Web Components и Hooks, вдохновлённая подходом React, но использующая нативные возможности браузера. Одной из ключевых задач при работе с большими списками элементов является оптимизация их рендеринга. Виртуализация списков позволяет существенно повысить производительность, рендеря только видимую часть элементов, а не весь массив данных одновременно.
Виртуализация списков заключается в том, что создаётся контейнер фиксированной высоты, внутри которого отображается только ограниченное количество элементов, соответствующее области видимости. Элементы, которые находятся вне видимой зоны, не создаются в DOM, что снижает нагрузку на браузер.
Основные компоненты подхода:
Haunted не предоставляет встроенного компонента для виртуализации, но её можно реализовать с помощью хуков, реактивного состояния и наблюдения за прокруткой.
useState и useEffectimport { html, component, useState, useEffect } from 'haunted';
function VirtualList({ items, itemHeight, viewportHeight }) {
const [scrollTop, setScrollTop] = useState(0);
const totalHeight = items.length * itemHeight;
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight));
const visibleItems = items.slice(startIndex, endIndex);
useEffect(() => {
const onScr oll = (e) => setScrollTop(e.target.scrollTop);
const container = document.getElementById('virtual-container');
container.addEventListener('scroll', onScroll);
return () => container.removeEventListener('scroll', onScroll);
}, []);
return html`
<div id="virtual-container" style="height:${viewportHeight}px; overflow-y:auto; position:relative;">
<div style="height:${totalHeight}px; position:relative;">
${visibleItems.map((item, i) => html`
<div style="position:absolute; top:${(startIndex + i) * itemHeight}px; height:${itemHeight}px; width:100%;">
${item}
</div>
`)}
</div>
</div>
`;
}
customElements.define('virtual-list', component(VirtualList));
Ключевые моменты:
overflow-y: auto
для прокрутки.scrollTop отслеживается через useState и
обновляется с помощью обработчика события scroll.const buffer = 3;
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - buffer);
const endIndex = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + buffer);
const renderItem = (item, index) => html`
<div style="position:absolute; top:${index * itemHeight}px; height:${itemHeight}px; width:100%;">
${item}
</div>
`;
scrollTop, используя requestAnimationFrame или
debounce.scrollTop или
данных.Виртуализация в Haunted строится на сочетании реактивного состояния, позиционирования элементов и прослушивания событий прокрутки. Такой подход позволяет обрабатывать списки из тысяч элементов без существенного снижения производительности. Использование буфера элементов и оптимизация рендера с помощью функций обеспечивает плавный пользовательский опыт даже при интенсивной прокрутке.