Part 5 · 2 chapters · ~12 min

Paint and Composite

From geometry to pixels: paint and display lists, raster and tiles, the compositor and its layers; then frames and their budget, animation that stays smooth, and media.

12

Paint, raster and layers

How geometry becomes pixels: recording, rastering in tiles, and the layers the compositor moves without repainting.

Paint

layout treepaintdisplay listrasterpixels

Recording drawing commands (display items) for each layer from the layout tree, in stacking order; not yet pixels.

in practiceGreen "Paint" slices in the Performance panel; Paint flashing in the Rendering drawer.

deep dive: Browser P5

Display list

DrawRect(0,0,800,600, #fff)DrawText("Checkout", 24,40)DrawImage(hero.webp, 0,80)DrawRRect(btn, r=6, #4338CA)

The ordered list of drawing operations (draw rect, draw text, draw image) paint produces, replayed later by raster.

in practiceWhy paint is cheap to record but raster can be expensive.

deep dive: Algorithms P4

Paint order

positive z-indexlastpositioned (z auto)inline contentfloatsblock childrennegative z / backgroundsfirst

The fixed order within a stacking context: backgrounds and borders, negative z, block children, floats, inline content, positioned and positive z.

in practiceWhy an absolutely positioned element paints over normal-flow siblings regardless of DOM order.

deep dive: Browser P5

Raster

tile ✓tile ✓tile ✓tile ✓tile ✓tile …tile …blanktiles raster in parallel; blank = checkerboarding

Turning display lists into pixels in tiles, usually on the GPU (GPU raster) in worker threads.

in practiceCheckerboarding when scrolling faster than tiles raster; huge blurred shadows that are slow to raster.

deep dive: Browser P5

Tiling

viewportviewportviewportviewport

Splitting each layer into tiles (often 256 px squares) that are rastered and cached independently, prioritised near the viewport.

in practiceSmooth scroll of big pages; memory cost of large layers.

deep dive: Browser P5

Compositor

main threadJS, style, layout, paintcan be busycompositor threadscroll, transform, opacitykeeps frames coming

The thread and process that assembles rastered layers into frames, applying transforms, opacity and scroll without the main thread.

in practiceWhy transform and opacity animations stay smooth during a long JS task.

deep dive: Browser P5

Compositing layer

layer: fixed headerlayer: animated card (will-change)root layer: the page

A part of the page rastered into its own texture so it can be moved, faded or scrolled by the compositor without repainting.

in practiceThe Layers panel; will-change: transform; video, canvas and fixed elements.

deep dive: Browser P5 · DevTools P8

will-change

.drawer { will-change: transform; } /* before */.drawer.open { transform: translateX(0); }/* remove it when the animation ends */

A hint that a property will animate, so the browser can promote the element to its own layer ahead of time.

in practicewill-change: transform on a drawer before it slides; overuse costs GPU memory for every promoted element.

deep dive: Browser P5

Layer explosion

layerlayerlayerlayerlayerlayerlayerlayerlayerlayerlayerlayeroverlap promotes everything above

Too many compositing layers, often from overlap: an element above a promoted one is promoted too, multiplying GPU memory.

in practiceThe Layers panel listing hundreds of layers; mobile tabs crashing from GPU memory.

deep dive: DevTools P8

Damage (invalidation rect)

damagedrepaint only the damaged rect

The region of the screen that changed and must be repainted; the rest of each tile is reused.

in practicePaint flashing showing green rectangles exactly where content changed.

deep dive: Browser P5

GPU process

renderercompositor framesGPU processraster, drawdisplay

The browser process that talks to the graphics driver, running raster and compositing work for all tabs.

in practicechrome://gpu; driver bugs that blacklist GPU features; a crashed GPU process blanking every tab briefly.

deep dive: Browser P0

Paint holding

page A pixelsheldpage B loadi…page B first…swap

Keeping the previous page's pixels on screen during a same-origin navigation until the new page has something meaningful to paint.

in practiceNo white flash between pages of a multi-page site.

deep dive: Browser P10
THE PAINT AND COMPOSITE LAYER, IN ORDER
from geometry to pixels on the glass, and the frame budget everything has to fit
swipe the figure sideways, or tap expand for full screen
1/6
paint
Paint: the layout tree is recorded as display lists in paint order; only damaged rectangles are repainted.
13

Frames, animation and media

The frame budget, how to animate inside it, and the media and drawing surfaces that decide how much pixel work there is.

Frame

inputrAFstylelayoutpaintcomposite16.7 ms budget

One complete visual update: input, animation callbacks, style, layout, paint, composite, presented at the display's refresh.

in practiceThe frames track in the Performance panel; 16.7 ms at 60 Hz, 8.3 ms at 120 Hz.

deep dive: Browser P5 · Browser P6

Frame budget

your work ~10 msbrowserheadroom16.7 ms at 60 Hz

The time available per frame at the refresh rate, minus browser overhead: about 10 ms of main-thread work at 60 Hz.

in practiceAnimations that drop frames when scripts take longer; why 120 Hz screens halve the budget.

deep dive: Browser P5

Jank

frame 1frame 2frame 3 (droppe…frame 496 ms

Visible stutter from missed frames, when work on a frame takes longer than the budget.

in practiceScroll handlers doing layout; image decoding on the main thread; the red frame markers in DevTools.

deep dive: Browser P5

requestAnimationFrame

taskrAF call…write DOM h…style, l…paint

Schedules a callback to run just before the next frame's style and layout, the right place for visual updates from script.

in practiceJS animations, batching DOM writes; callbacks pause in background tabs.

deep dive: Browser P6

Compositor-only animation

animate left / widthlayout each framepaint each framemain threadanimate transform / o…composite onlyoff main threadsmooth under load

Animating only transform and opacity (and filter in some cases) so the compositor runs it without main-thread style, layout or paint.

in practiceSmooth spinners during long tasks; animating top or width instead triggers layout every frame.

deep dive: Browser P5

Web Animations API

const a = card.animate( [{ transform: "scale(.96)" }, { transform: "none" }… { duration: 180, easing: "ease-out" });await a.finished;

element.animate(): the engine beneath CSS animations exposed to JS, with timelines, playback control and promises.

in practiceAnimations that need dynamic values and control (pause, reverse, seek) without libraries.

deep dive: Browser P5

View Transitions

snapshot…update D…snapshot…animate::view-tran…

A browser API that snapshots the old and new state of the page and animates between them, in a single document or across navigations.

in practicedocument.startViewTransition; cross-document transitions with @view-transition; shared-element morphs.

deep dive: Browser P10

Image decode

filedecoded4000×3000 JPEG (1.2 MB)48 MB bitmap, slow decode800×600 AVIF (60 KB)1.9 MB bitmap

Turning compressed image bytes (JPEG, WebP, AVIF) into a bitmap, which can be large and slow for big images.

in practice"Image Decode" slices; decoding="async"; serving images at display size so decode is not wasted.

deep dive: Browser P11 · FSD P3

Responsive images

<img src="hero-800.jpg" srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w" sizes="(min-width: 900px) 50vw, 100vw" width="1600" height="900" alt="…">

srcset and sizes let the browser pick the right resolution for the layout width and device pixel ratio; picture switches formats or art direction.

in practiceMobile devices downloading 400 px images instead of 2000 px ones; AVIF with a JPEG fallback.

deep dive: Browser P11 · FSD P3

Lazy loading

loadedloadednear: loadinglazylazylazyfetch when close to the viewport

Deferring offscreen images and iframes until they near the viewport, with loading="lazy" or IntersectionObserver.

in practiceNever on the LCP image; standard on below-the-fold media and embeds.

deep dive: Browser P11

Canvas vs SVG vs DOM

DOMretained, accessible, < ~1k…SVGretained, crisp, < ~5k elem…canvas 2Dimmediate, 10k+ pointsWebGL / WebGPUimmediate, 1M+ points

Three ways to draw: DOM and SVG are retained (the browser keeps objects you can style and hit-test); canvas is immediate (you draw pixels each frame).

in practiceCharts with thousands of points move to canvas or WebGL; accessible diagrams stay SVG.

deep dive: FSD P4 · FSD P2

OffscreenCanvas

mainworkertransferControlToOffscreen()draw frameshandle input (free)draw frames

A canvas that can be rendered in a worker, keeping heavy drawing off the main thread.

in practiceCharts and image processing that stay smooth while the UI thread handles input.

deep dive: FSD P2