Почему анимация GSAP зависает при частых нажатиях и как это исправить
При разработке интерфейсов на React с использованием библиотеки GSAP (GreenSock Animation Platform) разработчики часто сталкиваются с проблемой: при быстром переключении категорий анимация выезда блоков начинает тормозить, зависать или полностью пропадает. Это типичная ошибка, связанная с неправильным управлением жизненным циклом анимации в React-компонентах. Разберём причины и предложим рабочее решение.
Причина проблемы: накопление анимаций GSAP
В исходном коде при каждом изменении selectedCategory срабатывает useEffect, который создаёт новую анимацию через gsap.from(). Однако если пользователь кликает по кнопкам быстро, предыдущая анимация не успевает завершиться, а новая уже запускается. Без должной очистки старые анимации накапливаются, вызывая конфликты и зависания. Метод animationRef.current.kill() вызывается, но он не всегда успевает сработать до старта новой анимации, особенно при частых вызовах.
Как исправить: правильная очистка анимаций в useEffect
Ключевое решение - гарантировать, что предыдущая анимация будет остановлена до создания новой. Для этого нужно использовать функцию очистки (cleanup function) в useEffect. Вместо того чтобы вызывать kill() в начале эффекта, лучше вернуть функцию, которая выполнится при размонтировании компонента или перед следующим запуском эффекта.
Исправленный код с cleanup-функцией
Замените текущий useEffect на следующий:
useEffect(() => {
// Создаём новую анимацию
const animation = gsap.from(advantagesRef.current, {
opacity: 0,
y: -60,
duration: 1.2,
stagger: 0,
});
// Сохраняем ссылку для очистки
animationRef.current = animation;
// Функция очистки: убиваем анимацию при размонтировании или перерендере
return () => {
if (animation) {
animation.kill();
}
};
}, [selectedCategory]);Это гарантирует, что каждая предыдущая анимация будет остановлена до того, как начнётся новая. Дополнительно можно уменьшить длительность анимации или добавить небольшую задержку (debounce) на клики, чтобы снизить нагрузку.
Дополнительные советы по оптимизации анимаций GSAP в React
- Используйте
useRefдля хранения ссылок на анимации - это позволяет управлять ими вручную и избегать утечек памяти. - Настройте
staggerс умом: если элементы появляются с задержкой, увеличьтеdurationили используйтеstagger: 0.1для плавного каскада. - Избегайте частых перерендеров: оборачивайте функции-обработчики в
useCallback, чтобыuseEffectсрабатывал только при реальном изменении категории. - Проверяйте консоль на ошибки: удалите
console.log('animationRef')в продакшене, так как он может замедлять выполнение.
Заключение
Проблема зависания анимации GSAP при частых нажатиях решается правильной очисткой старых анимаций через cleanup-функцию в useEffect. Это стандартная практика для React-разработчиков, работающих с анимациями. После внесения изменений анимация будет работать плавно даже при быстром переключении категорий.