При работе с библиотекой ScrollMagic сцены (scenes) представляют собой основную единицу логики анимации, привязанной к прокрутке страницы. Каждая сцена создаёт свои обработчики событий и наблюдает за положением элемента на странице. При большом количестве сцен производительность страницы может значительно снизиться, поэтому важно понимать методы оптимизации их количества и структуры.
Создание отдельной сцены для каждого анимируемого элемента часто избыточно. Вместо этого можно:
const controller = new ScrollMagic.Controller();
const items = document.querySelectorAll('.animate');
const scene = new ScrollMagic.Scene({
triggerElement: '#section',
duration: '50%'
})
.on('enter', () => {
items.forEach(item => item.classList.add('visible'));
})
.addTo(controller);
Создание всех сцен сразу при загрузке страницы может вызвать задержки рендеринга. Решение — создавать сцены по мере необходимости:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && !entry.target.sceneCreated) {
new ScrollMagic.Scene({
triggerElement: entry.target,
duration: 200
})
.setClassToggle(entry.target, 'visible')
.addTo(controller);
entry.target.sceneCreated = true;
}
});
});
document.querySelectorAll('.lazy-section').forEach(el => observer.observe(el));
Такой подход позволяет уменьшить количество одновременно активных сцен и снижает нагрузку на память.
Если анимация должна срабатывать только один раз при попадании элемента в область видимости, создание полноценной сцены для каждого элемента может быть излишним. Альтернатива:
scroll или
использование requestAnimationFrame.Пример с requestAnimationFrame:
const elements = document.querySelectorAll('.fade-in');
function onScroll() {
elements.forEach(el => {
const rect = el.getBoundingClientRect();
if (rect.top < window.innerHeight * 0.8) {
el.classList.add('visible');
}
});
}
window.addEventListener('scroll', () => requestAnimationFrame(onScroll));
Такой метод избавляет от необходимости создавать отдельную сцену для каждого элемента и снижает нагрузку на ScrollMagic.
Слишком длинные сцены или сцены с большим количеством offset также влияют на производительность:
GSAP.const tl = gsap.timeline();
tl.from('.item1', {opacity: 0, y: 50})
.from('.item2', {opacity: 0, y: 50})
.from('.item3', {opacity: 0, y: 50});
new ScrollMagic.Scene({
triggerElement: '#container',
duration: '80%'
})
.setTween(tl)
.addTo(controller);
Если на странице присутствуют сцены, которые не должны работать на определённых устройствах или при определённых условиях:
scene.destroy(true) для удаления сцены и
её событий.if (window.innerWidth > 1024) {
new ScrollMagic.Scene({
triggerElement: '#desktop-only',
duration: 300
})
.setClassToggle('#desktop-only', 'active')
.addTo(controller);
}
Правильная организация и минимизация сцен позволяют поддерживать высокую производительность страницы даже при сложных анимациях, повышая отзывчивость и плавность прокрутки.