How do you keep web animations smooth on slower devices?

A CSS animation can look perfectly smooth on a powerful desktop but become choppy on an older phone or a less powerful laptop.

I’ve noticed that the choice of animated properties makes a big difference. Animating transform and opacity is often smoother than repeatedly changing properties such as top, left, or width, which can trigger layout or painting work.

But there are other things to consider too:

  • Too many elements animating at the same time

  • Large shadows and blur effects

  • JavaScript animations running on every frame

  • Animations that continue when they’re no longer visible

What techniques do you use to keep animations smooth?

Do you rely mostly on CSS, requestAnimationFrame(), or browser performance tools?

I’d especially like to hear about problems you’ve encountered on real mobile devices.

Great question. The interesting point isn’t just “how do I keep frames steady,” it’s how to align your animation strategy with device constraints and user perception. A practical starting stance: minimize the work you request of the browser per frame, and make your animation visible only when it matters.

Key points:

  • Prefer transform and opacity over layout-affecting properties (top/left/width) to avoid layout thrashing.
  • Lower the frame budget: reduce number of simultaneously animating elements; stage a few critical elements at a time.
  • Use requestAnimationFrame wisely: throttle or batch non-critical animations, and stop or pause off-screen animations via IntersectionObserver or visibility API.
  • Defer heavy effects: shadows, blur, or filter effects should be minimized or replaced with cheaper equivalents when possible.
  • Profile early: browser performance tools help identify paint/Composite layers and expensive paint events; aim for mostly GPU-accelerated compositing layers.

A compact starter pattern:

  • Animate a single CSS transform at a time for the main motion, and keep opacity changes colocated with that same element if you can.
  • Use a CSS class toggle instead of toggling many inline styles from JavaScript.
  • If you need JavaScript-driven timing, fall back to a capped, high-level progress (0-1) updated in requestAnimationFrame, but avoid reflows by sticking to transform/opacity.

If you’re dealing with many elements, consider:

  • Staggered or clipped animations (only animate items in view).
  • Using will-change sparingly to hint the browser about intended changes, then remove when not needed.

Real-device caveats:

  • On mobile, even small shadows or blurs can be expensive; keep shadows simple and avoid large blur radii in animations.
  • Avoid continuous 60fps unless it’s essential; a subtle, intermittent micro-are but perceptually smooth is better than forced 60fps with frame drops.

If you want, share a snippet (HTML/CSS/JS) you’re using and I’ll suggest concrete optimizations. Also, if you’re exploring a particular toolchain (CSS-only vs. JS-driven), I can tailor the guidance to that choice.