Understanding the Chromium Pre-Paint Rendering Phase

This article provides a comprehensive overview of the pre-paint phase in the Chromium web browser's rendering lifecycle. Sitting directly between the layout and paint stages, the pre-paint phase is responsible for two critical operations: building property trees and executing paint invalidation. By translating layout geometry into specialized data structures and identifying exactly which parts of the screen need updating, the pre-paint process enables Chromium to render complex web pages efficiently and maintain smooth frame rates.

Where Pre-Paint Fits in the Pipeline

The rendering pipeline in Chromium's Blink engine follows a strict sequence of steps to convert HTML, CSS, and JavaScript into pixels on a screen. After the browser parses the DOM, computes CSS styles, and calculates the geometric coordinates of elements during the Layout phase, it enters the Pre-Paint phase.

Pre-paint executes a depth-first traversal of the layout tree. It acts as an optimization bridge, taking the raw spatial data from the Layout phase and preparing it so the upcoming Paint and Composite phases can do their jobs with minimal overhead.

Building Property Trees

The first major task of the pre-paint tree walk is constructing and updating property trees. In modern Chromium architecture, visual effects and scrolling behaviors are decoupled from the layout hierarchy and organized into four distinct property trees:

  • Transform Tree: Manages CSS transforms (such as rotations, scaling, and translations) and coordinate space offsets.
  • Clip Tree: Defines the rectangular or rounded boundaries of elements that hide overflowing content, such as containers using the CSS overflow: hidden property.
  • Effect Tree: Handles pixel-level visual effects applied to elements, including opacity, CSS filters, blend modes, and masks.
  • Scroll Tree: Tracks scrollable areas, scroll offsets, and how scrolling behaviors are chained together across nested elements.

By isolating these properties into dedicated trees during the pre-paint phase, Chromium allows its compositor thread to handle tasks like scrolling or transform animations independently. When a user scrolls, the browser simply updates a node in the Scroll Tree rather than recalculating the entire page layout.

Issuing Paint Invalidations

The second core responsibility of the pre-paint phase is paint invalidation. Redrawing an entire webpage for every single frame is computationally expensive and leads to poor performance. To prevent this, Chromium caches the drawing instructions (display items) generated in previous frames.

During the pre-paint walk, the engine compares the current style and layout states against the data from the previous frame. If an element's visual appearance, dimensions, or position has changed, the engine marks that specific element as "invalid."

Paint invalidation occurs at two levels during this phase:

  1. Display Item Invalidation: Marks the specific drawing instructions (like background colors, borders, or text) that need to be re-recorded during the upcoming Paint phase.
  2. Raster Invalidation: Flags the actual pixel tiles on the screen that have been dirtied by the change, signaling to the compositor that those specific areas must be redrawn into bitmaps later in the pipeline.

If an element only changes a property managed by the compositor—such as a 3D transform—the pre-paint phase updates the Transform Tree without issuing a paint invalidation, saving significant processing time.

Preparing for Later Stages

In addition to property trees and invalidation, the pre-paint phase calculates crucial metadata required by subsequent stages of the rendering lifecycle. It computes the precise visual rectangles needed to trigger JavaScript IntersectionObserver callbacks and identifies elements that require hardware-accelerated compositing layers. By resolving these complex spatial relationships upfront, the pre-paint phase ensures the rest of the rendering pipeline executes quickly and predictably.