Загрузка элементов по требованию

Библиотека Muuri предоставляет гибкий способ организации сеток с динамическими элементами, поддерживая не только статическую загрузку, но и подгрузку контента по требованию. Это особенно важно для страниц с большим количеством элементов, где полная загрузка сразу может негативно сказаться на производительности и UX.

Инициализация сетки

Для начала создаётся базовая сетка Muuri:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layout: {
    fillGaps: true
  }
});
  • .grid — контейнер, внутри которого находятся элементы сетки.
  • dragEnabled — включает возможность перетаскивания элементов.
  • fillGaps — заставляет сетку автоматически заполнять пустые места после удаления или добавления элементов.

Подгрузка элементов динамически

Подгрузка элементов по требованию обычно реализуется через AJAX или современные методы fetch API. Сначала создаются новые элементы в DOM, а затем они добавляются в Muuri с помощью метода add().

async function loadItems(url) {
  const response = await fetch(url);
  const data = await response.json();
  
  const newItems = data.map(itemData => {
    const element = document.createElement('div');
    element.classList.add('item');
    element.innerHTML = `
      <div class="item-content">
        <img src="${itemData.image}" alt="${itemData.title}">
        <h3>${itemData.title}</h3>
      </div>
    `;
    return element;
  });

  // Добавление элементов в DOM
  const gridContainer = document.querySelector('.grid');
  newItems.forEach(el => gridContainer.appendChild(el));

  // Добавление элементов в Muuri
  grid.add(newItems);
}
  • Метод add(elements) принимает массив DOM-элементов и интегрирует их в сетку с анимацией.
  • Создание элементов перед добавлением позволяет сохранить консистентность структуры и стилей сетки.

Ленивая загрузка при прокрутке

Для больших сеток часто используется ленивая загрузка (infinite scroll). Прокрутка отслеживается через событие scroll или IntersectionObserver.

const observer = new IntersectionObserver(async (entries) => {
  for (const entry of entries) {
    if (entry.isIntersecting) {
      await loadItems('/api/more-items');
    }
  }
}, {
  root: null,
  rootMargin: '0px',
  threshold: 1.0
});

observer.observe(document.querySelector('.load-trigger'));
  • Элемент .load-trigger размещается внизу сетки.
  • Когда он становится видимым на экране, вызывается функция загрузки новых элементов.
  • IntersectionObserver работает эффективнее, чем постоянная проверка scroll-позиции, так как минимизирует нагрузку на основной поток.

Удаление и повторная сортировка элементов

После подгрузки новых элементов может потребоваться обновить сортировку или фильтры сетки:

grid.sort((a, b) => {
  return a.getElement().dataset.order - b.getElement().dataset.order;
});
  • Метод sort() принимает функцию сравнения и автоматически перестраивает сетку с анимацией.
  • Для фильтрации элементов используется метод filter(), позволяющий скрывать или показывать элементы по заданным критериям.
grid.filter(item => item.getElement().dataset.category === 'featured');

Оптимизация производительности

При динамической загрузке большого количества элементов важно учитывать:

  1. Фрагменты DOM — создание элементов в DocumentFragment перед добавлением в контейнер уменьшает количество перерисовок:
const fragment = document.createDocumentFragment();
newItems.forEach(el => fragment.appendChild(el));
gridContainer.appendChild(fragment);
grid.add(newItems);
  1. Дебаунс событий прокрутки — предотвращает чрезмерное количество вызовов функции подгрузки.
  2. Отложенная загрузка изображений — использование loading="lazy" для <img> ускоряет рендеринг сетки.
<img src="image.jpg" alt="..." loading="lazy">

Обработка ошибок загрузки

Для надёжной работы системы важно предусмотреть обработку ошибок при запросе данных:

async function loadItems(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) throw new Error('Ошибка загрузки данных');
    const data = await response.json();
    // создание и добавление элементов
  } catch (error) {
    console.error(error);
  }
}

Такой подход предотвращает поломку сетки при сетевых сбоях или некорректных данных.

Поддержка анимации при добавлении элементов

Muuri автоматически анимирует новые элементы при добавлении. Для более сложных эффектов можно использовать опцию show при добавлении:

grid.show(newItems, { 
  layout: 'instant', 
  instant: false 
});
  • Позволяет контролировать появление элементов с анимацией без пересоздания всей сетки.

Итоговая архитектура

В результате подгрузка элементов по требованию в Muuri строится по следующему принципу:

  1. Отслеживание позиции пользователя (scroll / IntersectionObserver).
  2. Асинхронная загрузка данных.
  3. Создание DOM-элементов и их добавление в контейнер.
  4. Интеграция элементов в Muuri через add().
  5. Применение сортировки, фильтров и анимаций.
  6. Оптимизация производительности и обработка ошибок.

Этот подход обеспечивает гибкую, высокопроизводительную сетку с плавной подгрузкой элементов и полной совместимостью с возможностями Muuri по сортировке, фильтрации и анимации.