skip to content

In a browser's rendering pipeline, what does the paint step actually produce, and how is that different from what the compositing step does?

level: juniorimportance: should knowfreq 52%

answer

  1. after layout, before anything visible
  2. a recording of drawing commands
  3. tiles, textures, raster workers
  4. the GPU assembles the frame
  5. same texture, different matrix

basics

~20 s

Paint records the drawing commands for each box — backgrounds, borders, text, shadows — into a list, per layer. Compositing rasterizes those layers into GPU textures and assembles them, with each layer's transform and opacity applied, into the frame on screen.

solid answer

~40 s

The browser goes style, then layout, then paint, then composite. Paint does not put pixels on screen: it walks the already-positioned boxes in paint order and records drawing operations — fill this rect, stroke this border, draw this text run — into a display list. Those recordings are then rasterized into bitmaps, usually in tiles and usually off the main thread. Compositing is the last step: the compositor takes each layer's rasterized texture, applies that layer's transform matrix and opacity, and draws the layers into the final frame in the right order, normally on the GPU. The split is what makes some changes cheap — moving or fading an existing layer needs no new recording and no re-raster, only different parameters handed to the GPU.

go deeper

for a junior

Be able to name the four stages in order — style, layout, paint, composite — and say plainly that paint records what to draw while compositing assembles the finished frame.

for a middle

Expect to explain the intermediate raster step, tiling, and the three levels of invalidation: geometry changes redo layout onward, colour changes redo paint onward, and layer transforms redo only the assembly.

for a senior

Show you can read a performance trace and tell a paint-bound frame from a layout-bound one, and name what makes rasterization expensive — large blur radii, big gradients, clipped rounded corners over a large area.

for a principal

Own the memory side of the tradeoff: layers buy composite-only updates with GPU texture memory, and on low-end devices that budget is what decides how aggressively a design can lean on promoted layers.

## Where paint sits in the pipeline A browser turns markup and CSS into pixels in a fixed sequence. Style resolves the used value of every property for every element. Layout gives every box a position and a size in the coordinate space of its containing block. **Paint** is the next step, and it is the first one that is about colour rather than geometry. **Composite** is the last, and it is the only one that produces something you can actually look at. ## What paint produces: a recording, not pixels Painting walks the laid-out boxes in paint order and records drawing operations: fill this rounded rectangle with this colour, stroke this border, draw this text run at this baseline in this font, draw this decoded image into this rect. The output is a **display list** (Chromium's term is a display item list; Gecko also calls it a display list) — a serialized recording of what to draw and in what order. Within one box the order is fixed by the CSS painting rules: background and borders first, then the box's content, then its positioned descendants, so overlapping content lands in a predictable order. Producing this recording is comparatively cheap, and it is replayable: the same recording can be rasterized again at a different scale without re-running style or layout. ## Raster: turning the recording into bitmaps Between paint and composite there is a step people often collapse into "paint": **rasterization**. The recorded commands are executed to produce actual bitmaps. Browsers rasterize in **tiles** so that a 20,000-pixel-tall scrolling document only turns the visible region (plus some margin) into pixels, and they do it off the main thread on raster workers, commonly with GPU acceleration. Each compositing layer is rasterized into its own texture or set of tile textures. ## Composite: assembling the frame The compositor holds a tree of layers. For each layer it knows a texture, a transform matrix, an opacity, a clip, and a position in the draw order. To produce a frame it emits GPU draw calls (quads) that place each texture on screen with those parameters applied. Nothing about the *content* of a layer is recomputed at this stage — the pixels already exist. That is the payoff of the split. There are three distinct levels of invalidation: ```css /* changes geometry -> layout, paint, raster, composite */ .a { width: 240px; } /* changes colour only -> paint, raster, composite (no layout) */ .b { background-color: #0af; } /* on a composited layer -> composite only, no new recording */ .c { transform: translateX(40px); } ``` The first invalidates everything downstream of layout. The second skips layout but throws away the layer's recording and its rasterized tiles. The third throws away nothing: the compositor draws the same texture with a different matrix. ## What a layer is, and what it is not A compositing layer is not a DOM concept and there is no one-to-one mapping to elements. The overwhelming majority of a page paints into a single layer — the document's own — and the browser only splits content out when it has a reason to (a running compositor animation, a 3D transform, a `<video>` or WebGL `<canvas>`, and similar). Layers cost GPU memory, roughly width times height times four bytes for a 32-bit texture, so a browser that promoted every element would run out of memory instantly. ## Where this shows up in real work - A frame that is dropped because of paint looks different from one dropped because of layout: in a devtools performance trace you see time in *Paint*/*Rasterize* rather than *Layout*. - Large blurred shadows, large `border-radius` with clipping, and large repeated gradients are expensive to *raster*, not to lay out; making the box smaller helps more than simplifying the DOM. - Scrolling can be cheap precisely because it is a composite-only operation on already-rasterized tiles, until something forces a new recording. ## Vocabulary that trips people up "Repaint" in casual usage means the recording plus raster were invalidated. "Recomposite" means only the assembly step ran. Saying "the browser repaints on every frame of a transform animation" is the classic mix-up: it recomposites, and that is exactly why the animation is smooth.

  • If paint does not put pixels on screen, what step actually turns the recorded commands into pixels?
    Rasterization, which sits between paint and composite. The display list is executed into bitmaps, normally in tiles covering the visible region plus a margin, on raster workers rather than the main thread, and often GPU-accelerated. Compositing then draws those rasterized textures into the frame.
  • Does every element get its own compositing layer?
    No. Most of a page paints into a single layer. The browser promotes content only when it has a reason — a running compositor-driven animation, a 3D transform, a `<video>` or WebGL `<canvas>`, a `will-change` hint. Each layer costs GPU memory, roughly width times height times four bytes, so promotion is rationed.
  • Which is more expensive to change, an element's background-color or its transform, and why?
    `background-color`, in the usual case. It invalidates the layer's paint recording and its rasterized tiles, so the browser must re-record and re-raster that region. A `transform` change on a composited layer invalidates nothing: the compositor redraws the existing texture with a different matrix.

saying these in an interview costs you the question

  • Says paint means the pixels are already on the screen
  • Thinks every DOM element becomes its own GPU layer
  • Uses paint and composite as interchangeable words
  • Believes paint happens before layout in the pipeline
  • Assumes rasterization always runs on the main thread

context