The Cost of a Frame

Users expect pages to be not only fast to load but also smooth and responsive at every point in their lifecycle. The Interaction to Next Paint (INP) metric is a direct measure of this: a good INP score means a page reliably reacted to user input. A large part of that responsiveness is JavaScript execution, but the visual result users actually see comes from a set of browser tasks collectively known as rendering.

To build interfaces that respond quickly, you need to understand how the browser turns HTML, JavaScript, and CSS into pixels, and ensure your code—and any third-party code you load—runs as efficiently as possible.

Frames and Time Budgets

A user interacting with a website on a mobile phone.
The refresh rate of a display is an important consideration when it comes to building websites that feel responsive to user input.

Most displays refresh 60 times per second, with each screen refresh being a frame.

Frames as shown in the performance panel of Chrome DevTools. As the cursor scrubs over the filmstrip near the top, an enlarged representation of each frame is shown within a tooltip as a mobile navigation menu animates to its "open" state.

The screen always refreshes at a fixed rate, but the browser may not always produce a new frame to match it. Any running animation or transition requires the browser to produce one frame per refresh. Simple math gives the browser 16.66 milliseconds per frame at 60Hz, but because the browser has its own overhead for each frame, all your work must fit inside roughly 10 milliseconds. Missing that budget drops the frame rate, and the page visibly judders—a phenomenon known as jank.

Time targets depend on the kind of change you're making. For animations, where object positions are interpolated between two points across many frames, hitting that 10 millisecond budget is critical. For discrete user interface changes that proceed from one state to another with no motion, the goal is a feeling of instantaneity. The oft-cited figure of 100 milliseconds still applies in spirit, but INP's "good" threshold is 200 milliseconds or lower to account for a wider range of device capabilities.

Whether you're aiming to keep animations jank-free or just commit a new state as quickly as possible, understanding the browser's pixel pipeline is essential.

The Pixel Pipeline

Five major stages make up the pixels-to-screen work that web developers can influence:

The full pixel pipeline, containing five steps: JavaScript, Style, Layout, Paint, and Composite.
The full pixel pipeline, illustrated.
  • JavaScript: Typically used to trigger visual changes, such as animating elements, sorting data, or adding DOM nodes. CSS animations, CSS transitions, and the Web Animations API can also drive visual changes without JavaScript.
  • Style calculations: The browser figures out which CSS rules match which elements based on selectors, applies those rules, and calculates the final styles for each element. For example, the selector .headline applies to any element with a class attribute containing that class.
  • Layout: Once styles are known, the browser calculates the geometry of the page: element sizes and positions. Because layout of one element can affect others (a wide <body> typically changes the dimensions of its children throughout the tree), this step can be computationally involved.
  • Paint: Filling in pixels for text, colors, images, borders, shadows, and every other visual aspect of elements. This is typically done onto multiple surfaces, often called layers.
  • Composite: The layers are drawn to the screen in the correct order so the page renders as expected, which matters especially for overlapping elements.

Every part of this pipeline is an opportunity to introduce jank or add latency to a visual update. You need to know which stages your code touches and limit changes to only those stages that are strictly necessary.

Note that "paint" actually encompasses two tasks: creating a list of draw calls, and filling in the pixels. The latter is called rasterization. When you see paint records in DevTools, that includes rasterization. In some architectures draw-call list creation and rasterization run on different threads, but that's not something you control as a developer.

Not every frame touches every stage. There are three common paths through the pipeline when JavaScript, CSS, or the Web Animations API makes a visual change.

Path 1: JS / CSS > Style > Layout > Paint > Composite

The full pixel pipeline, with none of the steps omitted.

Changing a layout property—geometry-affecting values like width, height, or left/top—forces the browser to check all other elements and reflow the page. Affected areas then need repainting, after which the painted layers are composited together.

Path 2: JS / CSS > Style > Paint > Composite

The pixel pipeline with the layout step omitted.

If the change is to a paint-only property such as background-image, color, or box-shadow, the layout step can be skipped. Avoiding layout work whenever possible removes what is often a significant source of latency for the next frame.

Path 3: JS / CSS > Style > Composite

The pixel pipeline with the layout and paint steps omitted.

If the changed property requires neither layout nor paint, the browser can go straight to compositing. This is the cheapest and most desirable path through the pipeline, and it's especially valuable for high-pressure scenarios like animations and scrolling. One notable Chromium optimization is that page scrolling generally happens entirely on the compositor thread, so even if the page's main thread is unresponsive, you can still scroll to see parts of the page that were previously drawn.

Web performance ultimately is about avoiding work while making any unavoidable work as efficient as possible. In practice, that often means working with the browser instead of against it. Keep in mind that each pipeline stage has different computational costs; some are inherently far more expensive than others.

Learning More

For a deep dive into diagnosing and fixing rendering bottlenecks, performance expert Paul Lewis offers a free course through Udacity that covers profiling apps, identifying the causes of suboptimal rendering performance, and exploring the browser rendering pipeline with an eye toward building fast, smooth websites.

Udacity course screenshot