В библиотеке Muuri виртуализация элементов позволяет эффективно управлять отображением большого количества карточек или элементов сетки, минимизируя нагрузку на DOM и повышая производительность интерфейса. Основная идея виртуализации заключается в том, чтобы в DOM находились только видимые пользователю элементы, а остальные элементы создавались динамически по мере необходимости.
Muuri изначально не предоставляет встроенный модуль виртуализации, однако её можно реализовать с помощью комбинации обработки прокрутки, динамического создания элементов и методов Muuri для управления положением и сортировкой элементов.
getBoundingClientRect() для контейнера и элементов
сетки:function isVisible(element, container) {
const rect = element.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
return rect.bottom >= containerRect.top && rect.top <= containerRect.bottom;
}
function renderItems(items, container) {
container.innerHTML = '';
items.forEach(item => {
const element = document.createElement('div');
element.className = 'item';
element.innerHTML = `<div class="item-content">${item.content}</div>`;
container.appendChild(element);
});
}
grid.add([elements]) — добавление новых элементов в
сетку.grid.remove([elements], { removeElements: true }) —
удаление элементов.grid.refreshItems() — обновление позиций и размеров
элементов.Пример интеграции:
const grid = new Muuri('.grid', {
layout: {
rounding: false
}
});
function updateVisibleItems(allItems, container) {
const visibleItems = allItems.filter(item => isVisible(item.element, container));
grid.remove(grid.getItems(), { removeElements: true });
grid.add(visibleItems.map(item => item.element));
grid.refreshItems();
grid.layout();
}
requestAnimationFrame или debounce:let ticking = false;
container.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
updateVisibleItems(allItems, container);
ticking = false;
});
ticking = true;
}
});
Кэширование размеров и позиций элементов Если элементы имеют фиксированные размеры, их вычисления можно кэшировать, что позволяет ускорить проверку видимости и обновление сетки.
Предзагрузка элементов за пределами видимости Чтобы избежать визуального «прыгания» при скролле, можно загружать небольшое количество элементов за пределами видимой области (buffer zone).
Muuri поддерживает динамическую фильтрацию и сортировку элементов с
помощью методов filter() и sort(). При
виртуализации эти методы интегрируются с динамически создаваемыми
элементами:
Пример:
function filterAndVirtualize(allItems, container, filterFunc) {
const filteredItems = allItems.filter(filterFunc);
updateVisibleItems(filteredItems, container);
}
Виртуализация идеально сочетается с бесконечной прокруткой. Стратегия следующая:
grid.add()
и их позиции автоматически пересчитываются.container.addEventListener('scroll', async () => {
if (container.scrollTop + container.clientHeight >= container.scrollHeight - 200) {
const newItems = await fetchNextItems();
allItems.push(...newItems);
updateVisibleItems(allItems, container);
}
});
.grid) должна иметь
фиксированную высоту с overflow: auto..item) рекомендуется
задавать фиксированные размеры или использовать
grid.layout.rounding: false, чтобы избежать дробных
координат.Эта стратегия виртуализации обеспечивает плавный пользовательский интерфейс даже при очень больших наборах данных, полностью используя возможности Muuri для динамического управления сеткой и анимацией элементов.