Lazy loading — техника, позволяющая загружать и рендерить элементы страницы только по мере необходимости, снижая нагрузку на браузер и ускоряя отображение контента. В контексте Masonry это особенно важно, так как сетка может содержать десятки и сотни элементов, и одновременная их отрисовка может привести к падению производительности.
Для корректной работы lazy loading в Masonry важно правильно инициализировать библиотеку и убедиться, что элементы добавляются динамически после загрузки:
import Masonry from 'masonry-layout';
import imagesLoaded from 'imagesloaded';
const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
// Обеспечение правильного отображения изображений
imagesLoaded(grid).on('progress', function() {
msnry.layout();
});
Здесь ключевое значение имеет imagesLoaded, которое
гарантирует, что Masonry пересчитает позиции элементов только после
полной загрузки всех изображений.
Lazy loading изображений может быть выполнен через атрибут
loading="lazy" в HTML:
<div class="grid-item">
<img src="image1.jpg" loading="lazy" alt="Описание">
</div>
Однако для динамически подгружаемых элементов потребуется дополнительная логика на JavaScript. Например, используя Intersection Observer:
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.addEventListener('load', () => {
msnry.layout();
});
observer.unobserve(img);
}
});
}, { rootMargin: '200px' });
lazyImages.forEach(img => observer.observe(img));
Ключевые моменты:
dataset.src хранит реальный путь изображения.msnry.layout()
для корректной перестройки сетки.rootMargin позволяет подгружать элементы заранее, когда
они почти видны пользователю.Для интеграции Masonry с бесконечной прокруткой необходимо добавлять новые элементы в DOM и сразу обновлять сетку:
function appendItems(itemsHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = itemsHTML;
const items = tempDiv.querySelectorAll('.grid-item');
grid.append(...items);
imagesLoaded(items).on('progress', function() {
msnry.appended(items);
});
}
Здесь msnry.appended(items) сообщает Masonry о появлении
новых элементов и пересчитывает их расположение.
msnry.layout() только после загрузки группы изображений, а
не каждого элемента отдельно.Lazy loading Masonry легко интегрируется с:
mounted
хуки можно инициализировать Masonry после рендеринга элементов.Для сеток с контентом переменной высоты важно:
imagesLoaded для каждого нового
блока.columnWidth) или процентная ширина
(percentPosition).const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.addEventListener('load', () => msnry.layout());
observer.unobserve(img);
}
});
}, { rootMargin: '200px' });
lazyImages.forEach(img => observer.observe(img));
function appendItems(itemsHTML) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = itemsHTML;
const items = tempDiv.querySelectorAll('.grid-item');
grid.append(...items);
imagesLoaded(items).on('progress', () => msnry.appended(items));
}
Такой подход обеспечивает плавное добавление контента, минимизирует нагрузку на браузер и сохраняет визуальную стабильность Masonry-сетки.