Библиотека Masonry предназначена для создания динамических сеток с равномерным распределением элементов по колонкам, наподобие “мозаики”. Одним из ключевых приёмов оптимизации работы с Masonry является пакетное добавление элементов. Этот подход позволяет добавлять сразу несколько элементов в сетку, минимизируя пересчёт расположения и улучшая производительность.
appended для пакетного добавленияMasonry предоставляет метод .appended() для интеграции
новых элементов в уже существующую сетку. Он принимает
NodeList, массив DOM-элементов или отдельный элемент,
который был создан динамически.
Пример:
const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
const newElements = document.createElement('div');
newElements.innerHTML = `
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
`;
const items = newElements.querySelectorAll('.grid-item');
msnry.appended(items);
Ключевой момент: .appended()
автоматически пересчитывает позиции только для добавленных элементов,
что гораздо эффективнее, чем полное обновление сетки через
.layout() после каждого добавления.
insert и append с фрагментамиДля оптимальной производительности рекомендуется создавать фрагменты DOM, а не добавлять элементы по одному. Это снижает количество операций с DOM и ускоряет рендер.
Пример с DocumentFragment:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 10; i++) {
const div = document.createElement('div');
div.className = 'grid-item';
div.textContent = `Элемент ${i+1}`;
fragment.appendChild(div);
}
grid.appendChild(fragment);
const newItems = fragment.querySelectorAll('.grid-item');
msnry.appended(newItems);
Преимущество: элементы создаются и добавляются в DOM одной операцией, а Masonry пересчитывает только их расположение, не трогая старые элементы.
При динамической подгрузке контента, например изображений через AJAX, важно учитывать момент полной загрузки контента, иначе Masonry может некорректно вычислить размеры блоков.
Пример с использованием imagesLoaded:
imagesLoaded(grid, function() {
const newItems = document.querySelectorAll('.grid-item-new');
msnry.appended(newItems);
});
Рекомендация: всегда использовать проверку загрузки
изображений перед вызовом .appended(), особенно если
элементы содержат картинки, так как Masonry рассчитывает позиции исходя
из фактических размеров элементов.
Для визуальной плавности можно комбинировать .appended()
с CSS-анимациями. Элементы добавляются с прозрачностью 0, а после
добавления Masonry обновляет сетку и активируется анимация.
Пример:
.grid-item {
opacity: 0;
transform: translateY(20px);
transition: all 0.4s ease;
}
.grid-item.show {
opacity: 1;
transform: translateY(0);
}
const newItems = document.querySelectorAll('.grid-item-new');
newItems.forEach(item => item.classList.add('show'));
msnry.appended(newItems);
Эффект: элементы появляются плавно и не нарушают текущий порядок сетки.
При добавлении десятков или сотен элементов важно:
DocumentFragment для минимизации операций
с DOM..appended() один раз для всех новых элементов,
а не по одному.Такая оптимизация предотвращает “мерцание” сетки и снижает нагрузку на рендер браузера.
fetch('/api/new-items')
.then(res => res.json())
.then(data => {
const fragment = document.createDocumentFragment();
data.forEach(itemData => {
const div = document.createElement('div');
div.className = 'grid-item grid-item-new';
div.innerHTML = `<img src="${itemData.img}" alt="">${itemData.text}`;
fragment.appendChild(div);
});
grid.appendChild(fragment);
const newItems = fragment.querySelectorAll('.grid-item-new');
imagesLoaded(grid, function() {
msnry.appended(newItems);
newItems.forEach(item => item.classList.add('show'));
});
});
Преимущества такого подхода:
Пакетное добавление элементов в Masonry — это сочетание
оптимизации DOM, правильного времени вызова
.appended() и аккуратного управления
визуальными эффектами. Следование этим правилам позволяет
строить высокопроизводительные сетки даже с большим количеством
динамического контента.