Animation that stutters is usually not caused by too much animation but by animating the wrong property. The same visible movement can ask the browser for wildly different amounts of work depending on how it is implemented.
What the browser does inside one frame
Smooth movement lives around sixty frames per second, which leaves roughly sixteen milliseconds per frame. Inside that window the browser works through this sequence.
What matters is how far back you send it. Properties that change an element’s size or position rerun layout, and not only for that element — siblings and ancestors may be repositioned too, which makes it the most expensive case. Colours and shadows skip layout but rerun paint. Only transform and opacity are handled at the composite stage, leaving the earlier steps alone.
Substitutions that make the same motion cheap
Most UI animation can be rewritten with the cheap properties. The result looks essentially identical and the browser simply does less.
Concretely: slide something across with translateX rather than left, grow it with scale rather than width. Fade things out with opacity instead of touching display or height. If a shadow needs to deepen on hover, do not animate the shadow value — put a second layer carrying the deeper shadow behind it and animate that layer’s opacity.
will-change helps, but overusing it backfires. It tells the browser to prepare a separate layer, and every layer costs memory. Apply it only to elements about to move, and remove it when they stop.
Set a budget: count, duration, concurrency
Even with the right properties, moving dozens of things at once is still slow. Deciding three things at design time makes implementation much easier.
The second-to-last line is worth explaining. If a script reads an element’s position on every scroll event and then writes styles, the browser must force pending work to finish in order to answer the read. Repeat that each frame and scrolling becomes visibly heavy. Scroll-linked effects can now be expressed in CSS alone, so moving this whole class of effect into the stylesheet is the safer route.
“Reduce motion” is a real request
Operating systems expose a reduced-motion setting and browsers pass it through as prefers-reduced-motion. For people who get dizzy or nauseated by movement, this is a need rather than a preference.
The important part of honouring it is that the default state must be the finished state. If an element only becomes visible inside an animation declaration, a reduced-motion visitor never sees the content at all. Build the static layout first and lay motion on top, and the page stays whole with motion off — and in browsers that do not support the feature at all.
Related first-screen performance topics are collected in the performance archive, and tuning motion across viewport widths is covered in the responsive series. Finding and fixing rendering bottlenecks on a live site is part of our optimization program.