Boosting Chromium Speed with CSS content-visibility

This article explores how the content-visibility CSS property significantly improves rendering performance in the Chromium web browser. By instructing the browser to skip the layout and painting stages for off-screen elements, content-visibility drastically reduces initial page load times and makes on-page interactions smoother. Below, we examine the Chromium rendering pipeline, how this property leverages CSS containment to defer rendering work, and how to prevent layout shifts during implementation.

The Problem with Default Rendering

To display a webpage, Chromium runs through a rendering pipeline consisting of several stages: Style, Layout, Paint, and Composite. By default, Chromium processes the entire DOM (Document Object Model) through all of these stages during the initial load.

If a webpage has a massive amount of content located far down the page (off-screen), Chromium still calculates the styles, dimensions, and pixel data for those hidden elements. This wastes CPU and GPU resources, blocking the main thread and delaying the time it takes for the user to see and interact with the visible part of the page.

How content-visibility Alters the Pipeline

The content-visibility property, specifically when set to auto, solves this inefficiency by introducing lazy rendering to Chromium. When you apply content-visibility: auto to a section of your webpage, Chromium checks if that element is currently visible in the user's viewport.

If the element is off-screen, Chromium skips the rendering work for that element's subtree (all of its child elements). Specifically, it bypasses the most resource-heavy phases of the pipeline:

  • Style (Partially skipped): Chromium calculates the styles for the parent element itself, but ignores the styles of all its descendant elements.
  • Layout (Skipped): Chromium does not calculate the geometry, position, or dimensions of the child elements.
  • Paint (Skipped): Chromium does not create paint records or rasterize pixels for any of the child elements.

Because the browser only processes the elements currently in the viewport, the initial rendering time drops significantly.

The Role of CSS Containment

Under the hood, Chromium achieves this optimization using another CSS feature called Containment. When content-visibility: auto is applied to an element, Chromium automatically enforces contain: layout style paint on that element.

This creates a boundary. It guarantees to the Chromium engine that nothing inside the element can affect the layout or visuals of anything outside of it.

When the element is off-screen, Chromium temporarily adds size containment to the mix. Size containment tells the browser to lay out the element as if it has no children, essentially treating the internal content size as 0px by 0px. Because Chromium knows the internal content has a size of zero and cannot affect the rest of the page, it safely aborts the rendering process for everything inside that container.

Just-in-Time Rendering on Scroll

The skipped content is not gone; it is merely deferred. Chromium uses an internal intersection observer to monitor the position of elements with content-visibility: auto.

As the user scrolls down the page and an off-screen element approaches the viewport, Chromium automatically removes the temporary size containment. It then runs the Style, Layout, and Paint stages for that specific element just in time for the user to see it. This spreads the rendering workload over time rather than forcing it all to happen at the initial page load.

Preventing Layout Shifts with contain-intrinsic-size

Because Chromium treats the unrendered children of an off-screen element as having a size of 0px by 0px, the browser initially thinks the webpage is much shorter than it actually is. As the user scrolls and elements are rendered, the page suddenly expands, causing the scrollbar to jump erratically.

To fix this in Chromium, developers pair content-visibility with the contain-intrinsic-size property:

.card-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

This property provides Chromium with a placeholder height (in this case, 500px) for the off-screen element. Chromium uses this estimated size to calculate the total page height accurately from the very beginning, ensuring the scrollbar remains stable while still skipping the rendering of the internal content. Once the element is scrolled into view and rendered, the auto keyword tells Chromium to remember the element's actual rendered height, preventing jumps if the user scrolls back up.