Packery — это мощная библиотека для построения сеток с динамическим расположением элементов, где важным аспектом является оптимизация загрузки контента. Ленивая загрузка (lazy loading) позволяет загружать элементы или изображения только по мере необходимости, что снижает первоначальное время загрузки страницы и уменьшает нагрузку на браузер.
let container = document.querySelector('.grid');
let pckry = new Packery(container, {
itemSelector: '.grid-item',
gutter: 10
});
window.addEventListener('scroll', () => {
let scrollPosition = window.scrollY + window.innerHeight;
let lastItem = container.lastElementChild;
if (lastItem.offsetTop < scrollPosition + 100) {
loadMoreItems();
}
});
function loadMoreItems() {
// AJAX-запрос или генерация новых элементов
let newItem = document.createElement('div');
newItem.className = 'grid-item';
newItem.innerHTML = '<img data-src="image.jpg">';
container.appendChild(newItem);
pckry.appended(newItem);
lazyLoadImage(newItem);
}
Здесь pckry.appended используется для
уведомления Packery о добавлении новых элементов, чтобы они корректно
распределились по сетке.
IntersectionObserver Этот подход позволяет
отслеживать, когда элемент появляется в области видимости браузера, и
подгружать изображение только в этот момент:function lazyLoadImage(item) {
let img = item.querySelector('img[data-src]');
if (!img) return;
let observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(entry.target);
}
});
});
observer.observe(img);
}
После установки изображения Packery необходимо пересчитать расположение:
img.onl oad = () => {
pckry.layout();
};
Это гарантирует, что сетка будет корректно перестраиваться при загрузке каждого изображения.
Packery предоставляет методы для динамического обновления сетки:
pckry.appended(elements) — уведомляет
сетку о новых элементах.pckry.layout() — пересчитывает позиции
всех элементов.pckry.reloadItems() — полностью
пересчитывает список элементов, если они были добавлены или удалены вне
контролируемого процесса.Пример комбинированного подхода с ленивой загрузкой:
function addItems(itemsData) {
let items = itemsData.map(data => {
let div = document.createElement('div');
div.className = 'grid-item';
div.innerHTML = `<img data-src="${data.src}">`;
lazyLoadImage(div);
return div;
});
items.forEach(item => container.appendChild(item));
pckry.appended(items);
}
DocumentFragment, чтобы снизить
количество перерасчетов:let fragment = document.createDocumentFragment();
items.forEach(item => fragment.appendChild(item));
container.appendChild(fragment);
pckry.appended(items);
Отложенная инициализация Packery: инициализация сетки после первой порции загруженных изображений уменьшает визуальные прыжки элементов.
Debounce для событий прокрутки: предотвращает частые вызовы функции загрузки:
function debounce(func, wait = 100) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
window.addEventListener('scroll', debounce(() => {
checkLoadMore();
}));
pckry.layout(), иначе сетка может «съехать».IntersectionObserver для подгрузки
изображений.pckry.appended().pckry.layout() после загрузки каждого нового
элемента.Этот подход позволяет масштабировать сетку, поддерживать быструю загрузку страницы и корректно обрабатывать динамический контент без сбоев в расположении элементов.