Анимации с использованием anime.js могут быть ресурсоёмкими, особенно на устройствах с ограниченной производительностью или при слабом интернет-соединении. В таких случаях важно предусмотреть механизмы отключения анимаций, чтобы интерфейс оставался отзывчивым и не вызывал лагов или нагрева устройства.
Ключевым подходом является детектирование возможностей устройства и предпочтений пользователя, после чего анимации либо упрощаются, либо полностью отключаются.
prefers-reduced-motionСовременные браузеры предоставляют системное свойство
prefers-reduced-motion, которое позволяет определить, хочет
ли пользователь минимизировать анимации.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReducedMotion) {
console.log('Анимации отключены в соответствии с предпочтениями пользователя');
} else {
anime({
targets: '.box',
translateX: 250,
duration: 1000,
easing: 'easeInOutQuad'
});
}
Объяснение ключевых моментов:
window.matchMedia('(prefers-reduced-motion: reduce)')
возвращает объект MediaQueryList.matches будет true, если
пользователь активировал опцию сокращения анимаций в настройках ОС.if можно полностью пропускать вызовы
anime() или использовать упрощённые анимации.Помимо системных предпочтений, рекомендуется учитывать характеристики устройства, такие как количество ядер процессора и поддержка графического ускорения.
const isLowEndDevice = navigator.hardwareConcurrency && navigator.hardwareConcurrency <= 2;
if (isLowEndDevice) {
console.log('Упрощение анимаций для слабого устройства');
// Упрощённая анимация
anime({
targets: '.box',
translateX: 250,
duration: 500,
easing: 'linear'
});
} else {
// Полная анимация
anime({
targets: '.box',
translateX: 250,
duration: 1000,
easing: 'easeInOutQuad'
});
}
Пояснения:
navigator.hardwareConcurrency показывает количество
логических процессоров.Иногда необходимо selectively отключать только часть анимаций, оставляя основные переходы. Для этого можно использовать флаг состояния анимации:
let animationsEnabled = !(prefersReducedMotion || isLowEndDevice);
if (animationsEnabled) {
anime.timeline({loop: true})
.add({
targets: '.circle',
scale: [0, 1],
opacity: [0, 1],
duration: 800,
easing: 'easeOutElastic(1, .8)'
})
.add({
targets: '.circle',
translateX: 200,
duration: 1200,
easing: 'easeInOutQuad'
});
} else {
// Статическое состояние
document.querySelectorAll('.circle').forEach(el => {
el.style.transform = 'translateX(200px) scale(1)';
el.style.opacity = '1';
});
}
Принцип работы:
animationsEnabled комбинирует проверку системных
настроек и производительности.anime.timeline() позволяет легко включать
или исключать целые блоки анимаций.Полное удаление анимаций не всегда оптимально. Можно заменить сложные эффекты на более лёгкие трансформации, такие как:
translate вместо rotate3dopacity вместо сложных кривых движенияanime({
targets: '.icon',
translateY: 20, // вместо сложного path движения
duration: 400,
easing: 'linear'
});
Преимущество: визуальный отклик остаётся, а нагрузка на устройство минимизируется.
Возможна реализация динамического включения/отключения анимаций на лету, например, при изменении системных настроек:
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
function handleReducedMotionChange(event) {
if (event.matches) {
anime.remove('.box'); // остановка всех текущих анимаций
document.querySelector('.box').style.transform = 'translateX(250px)';
} else {
anime({
targets: '.box',
translateX: 250,
duration: 1000,
easing: 'easeInOutQuad'
});
}
}
mediaQuery.addEventListener('change', handleReducedMotionChange);
Ключевые моменты:
anime.remove(target) немедленно прекращает текущие
анимации на целевом элементе.change позволяет реагировать на
изменение настроек пользователя без перезагрузки страницы.prefers-reduced-motion.Эти подходы обеспечивают плавный пользовательский опыт без потери функциональности интерфейса, даже на устройствах с ограниченными ресурсами.