Chapter 133·Intermediate·9 min read
Layout, Paint, and Composite
The browser's final three rendering stages — layout computes the exact geometry of every box, paint fills in the pixels, and composite assembles layers (often on the GPU) into the frame you see. Where a page becomes an image, and where it gets expensive.
July 24, 2026
At the end of the last chapter the browser held a render tree: every visible element, each tagged with its final computed styles. It knows a heading should be bold and 32 pixels. What it still doesn't know is where that heading goes — how wide it is, what y-coordinate it starts at, and what it shoves down the page. Turning styled boxes into an actual on-screen image is the browser's final act, and its most demanding. It happens in three stages: layout, paint, and composite — and understanding their order and cost is the foundation of every performance decision you'll make.
Layout: working out the geometry
Layout (older browsers and many developers call it reflow) is where the browser computes the geometry of the page: the exact size and position of every box in the render tree. This is a genuinely hard calculation, because almost nothing on the web has a fixed pixel size. You write width: 50%, flex: 1, margin: auto, font-size: 1.2rem, max-width: 60ch — and layout's job is to resolve all of it, in the right order, into concrete pixel coordinates.
Crucially, layout is interdependent. The size of one element affects its neighbours and its parent. A paragraph that wraps onto a third line pushes everything below it further down. A flex item that grows steals space from its siblings. So the browser can't compute boxes in isolation — it walks the tree resolving constraints, and a change in one place can ripple outward. Layout produces, for every visible node, a precise box: its width, its height, and its x/y position relative to the page.
Layout is the most expensive of the three stages, precisely because of that ripple effect: touching one element's geometry can force the browser to recompute a large portion of the tree. Hold that thought — it's the villain of the performance chapter.
Paint: filling in the pixels
Once every box has a size and a position, the browser knows where everything goes but hasn't drawn a single pixel. Paint is the stage that produces the actual visual output: it walks the laid-out render tree and generates the colours — text glyphs, background colours, gradients, borders, box-shadows, images. Think of layout as drafting the blueprint and paint as actually applying the ink.
Paint typically produces a list of drawing instructions ("fill this rectangle grey, draw this text here, stroke this border") rather than immediately touching the screen. And it doesn't necessarily happen as one flat image — a complex page is painted in pieces, which sets up the third stage.
Composite: assembling the layers
Modern browsers don't paint the whole page onto one canvas. Instead, they split it into multiple layers — think of them like sheets of transparent film stacked on top of each other — paint each layer independently, and then combine them into the final image. That final combination step is compositing.
Why bother with layers? Because once a layer is painted, moving or fading it becomes almost free. If a fixed header, a modal, or an animating element lives on its own layer, the browser can reposition or blend that layer without repainting its contents — it just re-composites the existing painted layers in a new arrangement. And this compositing work is frequently handed to the GPU, which is spectacularly good at exactly this kind of "move and blend rectangles" task.
This is the secret behind buttery-smooth animations. Certain properties — most famously transform and opacity — can be animated by the compositor alone, touching neither layout nor paint. The element is already painted onto its layer; the browser simply composites that layer at a new position or a new transparency each frame. That's why "animate with transform, not top/left" is repeated so often — and now you know the mechanism behind the advice.
The cost hierarchy that governs everything
Step back and notice the pattern, because it's the single most useful takeaway of the guide's technical half. The three stages have sharply different costs:
Layout is dear, paint is moderate, composite is cheap. And they run in order: a change that forces layout also forces a repaint and a re-composite behind it, so triggering layout is the most costly thing you can do. A change that only needs paint skips layout. A change that only needs compositing — transform, opacity — skips both.
| A change to… | Triggers |
|---|---|
geometry (width, top, font-size, adding a node) | layout → paint → composite |
appearance (color, background, box-shadow) | paint → composite |
transform, opacity (on a layer) | composite only |
That table is, essentially, frontend rendering performance in miniature. Fast pages are the ones that keep changes low on this ladder.
Where this leaves us
You've now followed a page across the entire pipeline: from HTML text, into the DOM; from CSS text, into the CSSOM; merged into the render tree; laid out into boxes; painted into pixels; and composited into the frame on your screen. That's the full journey from URL to pixels — the promise the guide opened with, delivered.
Two big questions remain. First: all of this — parsing, styling, layout, paint, and your JavaScript — runs mostly on a single thread, so how does a page stay responsive to clicks while it's busy? That's the event loop. Second: now that we know layout is expensive and compositing is cheap, how do we write code that stays on the cheap side? That's the final chapter on performance. Onward to the thread that runs it all.