Animation UX et performance en 2025 — Directives pratiques
Publié: 20 sept. 2025 · Temps de lecture: 5 min · Par la rédaction Unified Image Tools
Pourquoi l’animation en 2025
Les animations orientent l’attention et donnent du contexte. En 2025, elles doivent être rapides, accessibles et économes en énergie. Cette fiche vous aide à fixer un budget, choisir la bonne technique (CSS/WAAPI/Lottie/vidéo), et livrer sans régression.
Choisir le format
- Boucles courtes/UI: WebP/AVIF animés
- Réel/son: MP4/WebM (vidéo)
- Transparence: WebP animé (vérifiez le support AVIF pour la transparence)
Note: évitez les GIF/APNG lourds; préférez MP4/WebM et sprites modernes.
Modèle d’implémentation
Exemple HTML de vidéo courte avec fallback image :
<video autoplay loop muted playsinline width="640" height="360" preload="metadata">
<source src="/loop.webm" type="video/webm" />
<source src="/loop.mp4" type="video/mp4" />
{/* fallback */}
<img src="/loop.jpg" alt="Boucle courte" />
</video>
Conseils d’expérience
- Respectez
prefers-reduced-motion
et offrez une option d’arrêt. - Ne bloquez pas FCP/LCP: chargez tard et déclenchez proche de l’interaction.
- Utilisez une vignette statique; chargez l’animation/vidéo au clic.
Accessibilité — réduire le mouvement
@media (prefers-reduced-motion: reduce) {
.anim { animation: none !important; transition: none !important; }
}
Fournissez une alternative: fondu, changement d’opacité, ou coupure directe.
Couches de composition : déclenchez si nécessaire via will-change: transform, opacity
. Préférez animer transform
/opacity
pour éviter le layout et contrôlez le nombre de couches afin d’épargner la mémoire GPU.
Budget d’animation
- Durée: 120–240 ms pour micro-interactions; 300–500 ms pour transitions de page.
- Distance: < 80 px pour les contenus essentiels; longues trajectoires seulement hors LCP.
- Concurrence: pas plus de 2 animations simultanées dans le viewport critique.
Check-list
- [ ] Migration GIF → WebP/AVIF/vidéo
- [ ] Clarifier transparence et exigences de boucle
- [ ] Respect de
prefers-reduced-motion
- [ ] Lazy‑load et cache optimisés
Études de cas
- Indicateur de chargement: remplacé par CSS pur → −30 KB.
- Héros animé converti en vidéo: GIF 2,4 MB → WebM 420 KB (qualité perçue équivalente).
- Déclenchement au scroll:
IntersectionObserver
injectesrc
à 30 % de visibilité.
FAQ
- Q: À quelle largeur arrêter la vidéo ?
- R: Sur mobile, privilégiez
preload="none"
, boucle courte et muette; laissez l’utilisateur déclencher l’extension.
- R: Sur mobile, privilégiez
- Q: WebP ou AVIF ?
- R: AVIF compresse mieux; conservez WebP en compatibilité.
- Q: Impact SEO ?
- R: Ne dégradez pas LCP/CLS. Évitez l’autoplay héro; utilisez une image poster statique et une lecture différée.
- Q: Sous‑titres et accessibilité ?
- R: Pour les vidéos porteuses de sens, fournissez des sous‑titres et supportez clavier/pause/lecture/réglage du volume.
Principes de conception — mouvement intentionnel
- Sens: réserver le mouvement à l’explication d’un état, d’une hiérarchie ou d’une causalité.
- Sécurité: éviter les clignotements >3 Hz et les zooms/rotations agressifs (WCAG 2.3.1).
- Cohérence: un même composant garde tempo/éasing identiques.
- Réversibilité: si l’animation échoue, l’UI statique doit rester pleinement fonctionnelle.
Durées et easings (repères concrets)
- Micro-interactions: 120–180 ms,
cubic-bezier(.2,0,0,1)
ouease-out
court - Contenu/modales: 180–240 ms,
ease-out
- Transitions de page (cross-fade/slide): 240–320 ms,
ease-in-out
- Ressort (physique): amortissement 20–28, raideur 140–220 (repères)
.btn { transition: transform 160ms cubic-bezier(.2,0,0,1), box-shadow 160ms ease-out; }
.btn:active { transform: translateY(1px); }
Repères supplémentaires : cubic-bezier(0.2, 0, 0, 1)
; ressort : damping: 20–28, stiffness: 140–220
.
Exemples WAAPI
const el = document.querySelector('.btn');
el?.animate([
{ transform: 'translateY(0)', opacity: 0.8 },
{ transform: 'translateY(-4px)', opacity: 1 }
], {
duration: 160,
easing: 'cubic-bezier(.2,.7,.2,1)',
fill: 'both'
});
function springTo(el, to = 0, { stiffness = 180, damping = 22 } = {}) {
let v = 0, x = 1; const dt = 1/60;
function frame() {
const f = -stiffness * (x - to) - damping * v;
v += f * dt; x += v * dt;
el.style.transform = `translateY(${x * 20}px)`;
if (Math.abs(v) > 1e-3 || Math.abs(x - to) > 1e-3) requestAnimationFrame(frame);
}
frame();
}
Optimisations liées au scroll
- Déclenchez l’animation quand l’élément devient visible (25–33%).
- Minimisez le JS: utilisez
position: sticky
et évitez les calculs coûteux. - Privilégiez
transform/opacity
plutôt que top/left/width/height.
Lottie / CSS / Vidéo — arbitrage
- Lottie (vecteur JSON): icônes UI et illustrations légères; couleurs remplaçables, indépendant de la résolution.
- CSS: micro‑interactions; dépendances minimes, coût d’exécution bas.
- Vidéo: rendu photo/complexe; excellente compression; sous‑titres/son possibles.
Critère: « qualité d’image prioritaire → Vidéo » / « boucle UI légère → CSS/Lottie » / « transparence requise → Lottie/WebP animé ».
Mesure et profilage
PerformanceObserver
pour long tasks; DevTools pour layers
et paint
.
Mesurez CLS/INP et évitez les démarrages tardifs d’animation.
new PerformanceObserver((list) => {
for (const e of list.getEntries()) console.log(e.entryType, e.name, e.duration);
}).observe({ entryTypes: ['longtask', 'measure'] });
performance.mark('anim:start');
// … démarrer l’animation …
performance.mark('anim:end');
performance.measure('anim:duration', 'anim:start', 'anim:end');
const io = new IntersectionObserver(es => es.forEach(e => e.isIntersecting && e.target.classList.add('in')), { threshold: 0.3 });
document.querySelectorAll('.reveal').forEach(n => io.observe(n));
Énergie et sécurité visuelle
- Limitez surface/durée animée pour réduire la consommation et le jank.
- Évitez le flicker 3–60 Hz; respectez WCAG 2.3.1.
- Offrez pause/arrêt/masquage (WCAG 2.2.2).
Implémentation infaillible (sanity)
- [ ] Objectifs/KPI définis (CTR/dwell/complétion)
- [ ] Mouvement limité à
transform/opacity
(sans relayout) - [ ] Déclenchement par interaction ou visibilité (lazy)
- [ ] Règles Reduced Motion et UI d’arrêt manuel
- [ ] Test A/B si l’impact business est critique
FAQ étendue
- Q: Lottie devient lourd ?
- R: Réduisez primitives et framerate; sinon migrez vers vidéo.
- Q: Et si je dois garder un GIF ?
- R: Cas d’interop imposée uniquement; acceptez le compromis poids/qualité.
- Q: Scroll jank ?
- R: Combinez
requestAnimationFrame
+IntersectionObserver
, évitez l’abus dewill-change
.
- R: Combinez
Articles liés
Fondamentaux de l’optimisation d’images 2025 — Un socle fiable, sans tâtonner
Les bases actuelles pour des images rapides et soignées sur tout site. Dans cet ordre : Redimensionnement → Compression → Responsive → Cache pour une exploitation stable.
Priorités d’images en 2025 — fetchpriority, preload, HTTP/2 push (retiré)
Maîtrisez LCP avec `fetchpriority`, `preload`, tailles réactives et budgets de bande passante. Stratégies par type de page.