Rendering in Chrome: Layers, Textures, and the GPU

For most developers, the DOM is the mental model of a web page. What happens between that parsed document and the final screen image is far less understood. As browsers have moved to hardware-accelerated rendering, a more accurate picture requires understanding layers — intermediate GPU-friendly representations of page content that most web developers never interact with directly.

This is the Chromium port of WebKit. This is not web platform specification material; it's an implementation detail of Chrome's rendering architecture, one that's evolving quickly. The specific triggers and behaviors covered here reflect Chrome Canary 27 and can change, but the core concepts are stable enough to be useful for debugging and performance work.

In Chrome, there are RenderLayers, which correspond to DOM subtrees, and GraphicsLayers, which are subtrees of RenderLayers. The latter are what's uploaded to the GPU as textures — bitmaps moved from main memory into video memory, where they can be cheaply mapped onto simple rectangular meshes. That's the mechanism behind 3D CSS transforms and smooth scrolling.

When Does an Element Get Its Own Layer?

The DevTools "show composited layer borders" setting (under the Rendering heading in settings) highlights these layers on screen with orange borders. A simple page with no special properties might consist of a single layer. Adding a 3D rotation to a <div>, per the example below, pushes that element into its own layer.

Chrome's heuristics for splitting content into layers are not static, but currently any of the following will trigger layer creation:

  • A 3D or perspective transform CSS property
  • <video> using accelerated video decoding
  • <canvas> with a WebGL or accelerated 2D context
  • Composited plugins like Flash
  • An element with a CSS animation on opacity or an animated transform
  • An element with accelerated CSS filters
  • An element with a child that already has a compositing layer
  • An element rendered on top of a sibling that holds its own composited layer

Creating a layer has a cost: memory in system RAM and video memory, bookkeeping overhead, and the risk of overdraw when many large layers overlap. Layer creation should be informed, not automatic.

Animation and Repaint

Once a layer's contents are painted to a bitmap and pushed to the GPU, they don't need to be repainted if the content doesn't change. A transform animation, for example, can rotate a layer back and forth with zero paint operations in the timeline — all the work is compositing the existing texture at different positions.

When the DOM underneath changes, though, a repaint is inevitable. For example, clicking an input button that widens a rotated element by a pixel forces a relayout and a full repaint of that element's layer. The DevTools "show paint rects" feature and the timeline's paint events will expose these invalidations as red flashes and paint records.

Chrome tries to repaint only regions of a layer that were dirtied. The common cause of invalidation is DOM style manipulation or a relayout. The reliable way to diagnose this is: use DevTools Timeline and Show Paint Rects to spot unexpected repaints, then locate where the DOM was dirtied just before. When painting itself is slow, DevTools' continuous painting mode is the right tool to profile it.

The DOM-to-Screen Pipeline

Conceptually, producing a frame of a web page requires:

  1. Splitting the DOM into layers
  2. Painting each layer independently to software bitmaps
  3. Uploading those bitmaps to the GPU as textures
  4. Compositing the layers together into the final screen image

That's the full path for the first frame. Subsequent frames can take shortcuts:

  1. If only certain CSS properties like transforms or opacity change, nothing is repainted — existing textures on the GPU are simply recomposited.
  2. If part of a layer is invalidated, only that portion needs repainting and re-upload. If content is unchanged but its composite attributes shift, the layer stays on the GPU.

This model has direct implications for rendering performance. The expensive part is painting; compositing is relatively cheap. Avoiding unnecessary repaints of layers is a solid strategy. But creating layers where none were warranted introduces memory pressure and complexity, so forcing creation of layers to optimize animations can backfire. The goal is to repaint as little as necessary, not to maximize layer count.

More articles are planned on the practical implications of Chrome's layer-based rendering architecture.