DEV Community

Cover image for How We Build High-Performance Animated Websites Without Killing Page Speed
Pixel Mosaic
Pixel Mosaic

Posted on

How We Build High-Performance Animated Websites Without Killing Page Speed

Modern web users expect two things at the same time: smooth, delightful animations and instant page loads. The problem? Most teams accidentally sacrifice performance in the name of motion.

But it doesn’t have to be that way.

This is a practical breakdown of how to build high-performance animated websites using tools like CSS animations, GSAP, and Framer Motion, without tanking Core Web Vitals.

The Core Principle: Animate What the Browser Likes

Before touching any library, understand this:

The browser animates some properties cheaply, and others very expensively.

Animate (fast):

  • transform (translate, scale, rotate)
  • opacity

Avoid (slow):

  • width, height
  • top, left, right, bottom
  • layout-triggering properties

Why?

Because expensive properties trigger reflow + repaint, while transform/opacity can stay on the GPU.

1. CSS First: The Performance Baseline

Never reach for a JS animation library first. CSS can handle more than you think.

Example: Smooth hover animation

.card {
  transform: translateY(0);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-8px);
  box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}
Enter fullscreen mode Exit fullscreen mode

Why this works well:

  • No JavaScript
  • GPU-accelerated
  • Minimal layout impact

2. GSAP: When You Need Control Without Chaos

GSAP shines when animations become complex (timelines, scroll-based effects, orchestration).

Key rule: Keep it transform-based

gsap.to(".box", {
  x: 200,
  opacity: 0.8,
  duration: 1,
  ease: "power2.out"
});
Enter fullscreen mode Exit fullscreen mode

Avoid:

  • Animating layout properties unless absolutely necessary
  • Running too many simultaneous timelines

Pro optimization tip:

Use will-change sparingly:

.box {
  will-change: transform;
}
Enter fullscreen mode Exit fullscreen mode

Remove it after animation if possible—overuse can hurt performance.

3. Framer Motion: React-Friendly, But Easy to Misuse

Framer Motion is amazing for React apps, but it can silently degrade performance if overused.

Good pattern:

<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.4 }}
>
  Hello
</motion.div>
Enter fullscreen mode Exit fullscreen mode

Optimization strategies:

1. Avoid animating large component trees

Break animations into smaller isolated components.

2. Use layout sparingly

Layout animations are powerful but expensive:

<motion.div layout />
Enter fullscreen mode Exit fullscreen mode

Use only when necessary (e.g., draggable cards, dynamic grids).

3. Prefer transform variants

Stick to x, y, scale, opacity.

4. The Real Performance Killer: Uncontrolled Mounting

It’s not always animation itself—it’s when animations run on:

  • Too many elements at once
  • Offscreen components
  • Unmounted DOM still being animated

Fix: Lazy-render animations

{isVisible && (
  <motion.div
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
  />
)}
Enter fullscreen mode Exit fullscreen mode

Or use intersection-based triggers:

  • IntersectionObserver
  • Scroll-triggered animation start

5. Lazy Loading Everything That Moves

If it’s not above the fold, don’t load it immediately.

Strategies:

  • Lazy load sections
  • Defer animation libraries
  • Split bundles (code splitting)

Example:

const AnimationSection = React.lazy(() => import("./AnimationSection"));
Enter fullscreen mode Exit fullscreen mode

Combine with:

<Suspense fallback={<Skeleton />}>
  <AnimationSection />
</Suspense>
Enter fullscreen mode Exit fullscreen mode

6. Scroll Animations: The Hidden Performance Trap

Scroll animations are where most websites break performance.

Bad:

  • Listening to raw scroll events
  • Updating state on every scroll tick

Good:

  • Use requestAnimationFrame
  • Use GSAP ScrollTrigger (optimized internally)
  • Or intersection observers

7. Reduce Repaints with Layer Isolation

Force GPU layer creation strategically:

.animated-element {
  transform: translateZ(0);
}
Enter fullscreen mode Exit fullscreen mode

But don’t spam it—too many layers = memory overhead.

8. Measure Everything (Seriously)

You cannot optimize what you don’t measure.

Track:

  • FPS drops
  • Layout shifts (CLS)
  • Long tasks
  • Paint time

Tools:

  • Chrome Performance tab
  • Lighthouse
  • Web Vitals extension

9. A Simple Mental Model That Works

When adding animation, always ask:

  1. Does this animation affect layout?
  2. Can I use transform/opacity instead?
  3. Is this element visible on screen?
  4. Can I delay or lazy-load it?

If the answer is “no optimization needed,” it probably needs optimization.

Final Thought

High-performance animation is not about choosing GSAP vs Framer Motion vs CSS.

It’s about this mindset:

“Move less, move smarter, and let the browser do the work.”

When you respect the browser’s rendering pipeline, you can build interfaces that feel premium without sacrificing speed.

Top comments (0)