Creating smooth, high-performance animations is essential for delivering great user experiences in modern web applications. Laggy or janky animations can frustrate users and hurt your app's perceived quality.
This guide will walk you through best practices for performant animations in CSS and JavaScript, cover tools like GSAP and Framer Motion, and highlight common pitfalls to avoid.
What Makes an Animation Performant?
To ensure your animations feel smooth and consistent at 60 FPS (or higher), keep these fundamentals in mind:
1. Leverage GPU (Hardware Acceleration)
Modern browsers can offload rendering to the GPUβββbut only if you animate the right properties.
The key is to stick with:
transform
opacity
These are GPU-accelerated properties and wonβt trigger costly reflows or repaints.
2. Avoid Layout Thrashing (Reflow & Repaint)
Some CSS properties are expensive because they trigger layout recalculations and painting. Avoid animating:
-
width
,height
,top
,left
,margin
-
background-color
,box-shadow
(when done excessively)
β
Instead:
Use transform: translate()
instead of top/left
, and animate opacity
instead of toggling visibility
.
Why Only transform
and opacity
Are GPU-Accelerated
When something on the page changes, the browser goes through a rendering pipeline:
- Main Thread: Handles JavaScript, layout, and style recalculation.
- Compositor Thread: Responsible for painting layers and compositing.
- GPU Thread: Handles hardware-accelerated drawing.
β
Animating transform
and opacity
only affects the compositing stage, bypassing layout and paint.
β Animating properties like top
or width
forces recalculation of layout and paint, blocking the main thread.
Hereβs a breakdown of CSS properties and their performance impact:
CSS Animations: First Choice for UI Effects
For simple interactions, CSS transitions and keyframes are your best bet.
Example: Hover Animation (GPU-Friendly)
.box {
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
}
.box:hover {
transform: scale(1.1);
opacity: 0.8;
}
β This works smoothly because it only animates transform
and opacity
.
Pro Tip: Use will-change
(But Wisely)
.box {
will-change: transform, opacity;
}
will-change
hints to the browser that an element will change soon, so it can optimize rendering ahead of time.
β οΈ Donβt overuse it β reserving GPU layers unnecessarily can hurt performance.
JavaScript Animations: When You Need More Control
For complex animations, JavaScript with requestAnimationFrame()
is the way to go.
Example: Smooth Movement
function animateBox() {
const box = document.getElementById("box");
let start = null;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
box.style.transform = `translateX(${Math.min(progress / 5, 300)}px)`;
if (progress < 1500) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
document.getElementById("start").addEventListener("click", animateBox);
β requestAnimationFrame()
syncs with the browserβs rendering cycle, reducing jank.
Why Not setInterval()
for Animations?
- β Runs on fixed intervals (not synced to refresh rate).
- β Keeps running in inactive tabs, wasting resources.
- β Causes stutters under heavy load.
β
requestAnimationFrame()
adapts to the refresh cycle and pauses in inactive tabs.
Animation Libraries You Should Know
GSAP (GreenSock Animation Platform)
- High-performance, widely used.
- Handles browser quirks and optimizations.
gsap.to(".box", { x: 300, duration: 1, ease: "power2.out" });
β Best for: complex timelines, SVG animations, and cross-browser consistency.
Framer Motion (for React)
- Declarative, React-first animation library.
- Works seamlessly with React components.
import { motion } from "framer-motion";
const Box = () => (
<motion.div animate={{ x: 100 }} transition={{ duration: 0.5 }} />
);
β Best for: React apps, UI interactions, and component-based motion.
Which Animation Tool to Use When?
- CSS Transitions/Keyframes β Simple hover, fade, or UI effects.
-
JavaScript (
requestAnimationFrame
) β Custom logic, physics-based movement. - GSAP β Complex animations, timelines, SVGs, cross-browser needs.
- Framer Motion β React-based UIs needing declarative animations.
Final Takeaways
- Use
transform
andopacity
for smooth, GPU-accelerated animations. - Avoid layout-thrashing properties like
width
andtop
. - Prefer CSS for simple effects, JS for complex logic.
- Reach for GSAP or Framer Motion when building interactive, production-grade animations.
Top comments (0)