Layout, paint, and composite

Layout places boxes, paint draws them, and composite stacks the finished layers. The earlier in that chain a change lands, the more work a frame costs.

which css changes trigger layoutwhy is animating top slower than transformwhy does scrolling stutterreflow vs repaintthe animation is choppy on phonescompossiting layerpurple and green bars in chrome devtoolswhy does this css animation jank

See it

Live demo coming soon

What it is

Layout calculates the size and position of boxes. Paint records how those boxes, text, borders, and shadows should look. Composite assembles painted layers into the final frame. A geometry change such as 'width' can require all three; a color change can require paint and composite; an animation of an already promoted 'transform' or 'opacity' can often stay in the compositor.

Use this cost ladder when an interaction or animation misses frames. Chrome DevTools marks Layout in purple and Paint in green, while its Layers tools show which content has been promoted. Moving work down the ladder is usually more valuable than shaving a tiny amount from the same expensive stage.

Gotcha: compositor work is not free, and 'will-change' is not a speed spray. Extra layers consume memory and can create their own raster and upload cost. Add 'will-change' shortly before a real animation, remove it afterward, and trust a recorded frame trace over a lookup table of supposedly cheap CSS properties. The old CSS Triggers site is a decent mental model and a bad source of truth: which stages a property fires depends on the engine, the version, and what else is on the page.

Ask AI for it

Profile this animation in Chrome DevTools Performance with Paint flashing enabled. Identify every frame that triggers Layout or Paint, then rewrite motion based on 'top', 'left', 'width', or 'height' to use 'transform', and replace visibility fades with 'opacity' where the visual result stays the same. Use 'will-change: transform' only on elements about to animate and remove it on 'transitionend' or 'animationend'. Verify the Layers panel does not show uncontrolled layer growth, record the before and after main-thread rendering cost, and confirm the animation holds its target frame rate.

You might have meant

layout thrashingcumulative layout shiftinteraction to next paintmain thread blockinglong task