Muuri — это мощная библиотека для создания динамических сеток в JavaScript с поддержкой перетаскивания, анимаций и адаптивного расположения элементов. При работе с большим количеством изображений важно оптимизировать загрузку контента, чтобы улучшить производительность и снизить время отклика страницы. Ленивая загрузка (lazy loading) позволяет загружать изображения только тогда, когда они становятся видимыми в области просмотра.
Ленивая загрузка особенно полезна в сетках Muuri, где элементы могут динамически изменять размер, перемещаться или добавляться после инициализации.
<script src="https://cdn.jsdelivr.net/npm/muuri@0.10.5/dist/muuri.min.js"></script>
<div class="grid">
<div class="item">
<div class="item-content">
<img data-src="image1.jpg" alt="Image 1" class="lazy">
</div>
</div>
<div class="item">
<div class="item-content">
<img data-src="image2.jpg" alt="Image 2" class="lazy">
</div>
</div>
</div>
Важное отличие: вместо атрибута src используется
data-src. Это позволяет избежать загрузки всех изображений
сразу.
const grid = new Muuri('.grid', {
layout: {
fillGaps: true
}
});
Современный и эффективный способ реализовать ленивую загрузку — Intersection Observer API. Он позволяет отслеживать, когда элемент становится видимым в окне браузера.
const lazyImages = document.querySelectorAll('img.lazy');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
img.addEventListener('load', () => {
// Обновление расположения сетки после загрузки изображения
grid.refreshItems().layout();
});
observer.unobserve(img);
}
});
}, {
rootMargin: '100px 0px', // загрузка немного заранее
threshold: 0.1
});
lazyImages.forEach(img => observer.observe(img));
Ключевые моменты:
rootMargin позволяет подгружать изображения заранее,
предотвращая появление пустых областей.grid.refreshItems().layout() после загрузки
гарантирует корректное перераспределение элементов сетки.observer.unobserve(img) освобождает ресурсы после
загрузки элемента.Muuri часто используется для сеток с динамическим контентом. Если новые элементы добавляются после инициализации, необходимо наблюдать их также:
function observeNewItems(newItems) {
newItems.forEach(item => {
const img = item.querySelector('img.lazy');
if (img) observer.observe(img);
});
}
// Пример добавления нового элемента
const newItemHTML = `
<div class="item">
<div class="item-content">
<img data-src="image3.jpg" alt="Image 3" class="lazy">
</div>
</div>`;
const tempDiv = document.createElement('div');
tempDiv.innerHTML = newItemHTML;
const newItemElement = tempDiv.firstChild;
grid.add(newItemElement);
observeNewItems([newItemElement]);
Это гарантирует, что все новые изображения будут подгружаться лениво и сетка останется корректной.
Для более плавного появления изображений можно использовать CSS-переходы:
img.lazy {
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
img:not(.lazy) {
opacity: 1;
}
После того как изображение загружается, класс lazy
удаляется, и картинка плавно появляется в сетке. Это улучшает визуальное
восприятие при динамическом добавлении или прокрутке элементов.
scroll, так как API оптимизирован для работы с большим
количеством элементов.let pendingRefresh = false;
function scheduleRefresh() {
if (!pendingRefresh) {
pendingRefresh = true;
requestAnimationFrame(() => {
grid.refreshItems().layout();
pendingRefresh = false;
});
}
}
data-src и Intersection
Observer.rootMargin.Эта техника позволяет создавать высокопроизводительные сетки Muuri с большим количеством изображений, обеспечивая плавность анимаций, минимизацию задержек и аккуратное размещение элементов при динамическом изменении контента.