Web Animation Performance: What to Animate and What to Avoid

A SaaS dashboard client wanted a polished feel to sidebar and modal transitions, but the initial implementation animated width, height, and top/left position directly, which forces the browser to recalculate layout on every frame. On a mid-tier laptop, opening the sidebar dropped frame times to around 40ms, well past the 16.6ms budget for 60fps, and it was visibly janky on anything but the newest hardware.
The fix was restricting animation to properties the compositor can handle without triggering layout or paint: transform and opacity. Instead of animating width from 0 to 280px, we animate a translateX from -280px to 0 on a fixed-width element, and instead of animating top for a dropdown's position, we use transform: translateY. This moved the work off the main thread entirely and got frame times down to a consistent 6-8ms.
We also added will-change: transform selectively on elements right before they animate, and removed it after, rather than leaving it applied permanently. Static will-change on many elements was actually hurting performance by forcing the browser to keep unnecessary composite layers around, which showed up as increased memory usage in Chrome's performance panel.
Not everything should be animated just because it can be. We pushed back on animating list re-ordering in a data table with hundreds of rows — FLIP-technique animations look great with 10 items and become a jittery mess with 200, since each animated row is its own layer. We kept the row entrance animation but dropped animated re-sorting in favor of an instant re-render with a brief highlight flash, which tested better with users anyway.
For clients asking for parallax or scroll-linked effects, we default to CSS scroll-driven animations where browser support allows, falling back to a throttled IntersectionObserver rather than a scroll event listener, since unthrottled scroll listeners doing layout reads were the single most common cause of scroll jank we found across audits.
The general rule we now hand to every frontend dev on the team: if an animation touches anything other than transform, opacity, or filter, profile it in DevTools before shipping. It takes two minutes and it's caught real regressions before they reached production.

