Главное правило: анимируй только transform и opacity
Браузер перерисовывает страницу (repaint) каждый раз, когда меняются width, height, top, left, background. Transform и opacity работают на GPU — без перерисовки страницы.
// Плохо — вызывает layout reflow
gsap.to(el, { left: 100, width: 200 })
// Хорошо — GPU, без reflow
gsap.to(el, { x: 100, scaleX: 1.5 })ScrollTrigger: паттерны которые работают
Reveal при скролле
gsap.from('.card', {
scrollTrigger: {
trigger: '.card',
start: 'top 85%',
},
y: 40,
opacity: 0,
duration: 0.7,
ease: 'power3.out',
stagger: 0.1,
})Pinned секция
ScrollTrigger.create({
trigger: '.section',
start: 'top top',
end: '+=500',
pin: true,
scrub: 1,
})will-change: когда помогает, когда вредит
will-change: transform говорит браузеру заранее создать GPU-слой. Ускоряет анимацию, но использует видеопамять. Правило: добавляй непосредственно перед анимацией и убирай после.
gsap.to(el, {
onStart: () => el.style.willChange = 'transform',
onComplete: () => el.style.willChange = 'auto',
x: 200,
duration: 0.6,
})Частые ошибки
- ◆Анимация сбрасывается при ресайзе — используй once: true для одноразовых анимаций
- ◆box-shadow в анимации — вызывает repaint. Для анимированных теней — псевдоэлемент с opacity transition
- ◆Не чистишь триггеры в React — обязательно: return () => ctx.revert() в useEffect
- ◆Слишком много одновременных анимаций — группируй в timeline, контролируй overlapping
Нужно что-то похожее?
Обсудим вашу задачу — отвечу в течение часа.