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.