A janky animation is worse than no animation at all — it draws attention to itself for the wrong reason. Most of the time, the difference between a buttery-smooth transition and one that stutters isn't the animation library or the easing curve, it's which CSS properties are actually being animated.

The browser's rendering pipeline, briefly

Every frame, the browser roughly does three things: layout (work out the size and position of everything), paint (work out pixels and colours), and composite (combine already-painted layers on the GPU). The further up that list a property change forces the browser to go back to, the more expensive the frame is.

What this means in practice

Prefer transform and opacity for anything that needs to run smoothly, especially on lower-powered devices:

If you genuinely need to animate something like height (an accordion expanding, for instance), it's often smoother to animate max-height or a grid-template-rows trick, or to measure the element's height once with JavaScript and animate to that fixed pixel value with transform: scaleY() instead — depending on how forgiving the layout around it is.

The will-change property is a hint, not a switch

will-change: transform tells the browser to promote an element to its own compositor layer ahead of time, which can help avoid a jump the first time an animation runs. It's easy to overuse, though — promoting too many elements to their own layers eats GPU memory and can make things slower, not faster. Use it sparingly, on elements you know are about to animate, and remove it once the animation is done rather than leaving it on permanently.

Watch what you're stacking on top of GSAP or Framer Motion

Animation libraries are good at scheduling and easing, but they can't rescue an animation that's targeting an expensive property. If a GSAP tween feels stuttery, the first thing worth checking is what property it's actually touching — often the fix is switching the tween's target from a layout property to a transform, not tweaking the library's configuration.

Respect reduced motion

Not every visitor wants motion, and for some it's genuinely uncomfortable. Wrap non-essential animation in a prefers-reduced-motion check and provide a calmer (or instant) alternative — this matters for accessibility as much as it does for performance.

Measure it, don't guess

Chrome DevTools' Performance panel and the Rendering tab's "Paint flashing" and "Layout Shift Regions" overlays make it obvious, in seconds, whether an animation is triggering layout or paint it doesn't need to. It's a five-minute check that saves a lot of guesswork.

Animation feeling sluggish?

Often it's a one-line fix once you know which property is the culprit — happy to take a look.

← Back to the blog