ScreenshotNeo

BlogEngineering

CSS content-visibility: How to Improve Page Rendering Performance

Use CSS content-visibility to defer rendering of offscreen sections. Learn how to size placeholders, avoid accessibility and layout pitfalls, and measure the results.

By the ScreenshotNeo team4 October 20268 min read

content-visibility: auto can reduce the work a browser does to lay out and paint a long page by letting it skip rendering substantial offscreen sections until they become relevant. Apply it to independent content chunks and pair it with contain-intrinsic-size so skipped sections reserve plausible space. Then measure the page on the devices and browsers your visitors use: the improvement depends on how much rendering work can be skipped.

1. What content-visibility changes

The CSS content-visibility property controls whether an element’s contents are rendered. With auto, the browser can skip rendering work for offscreen content, including layout and painting, until it needs to render that content. The content remains in the DOM; this is a rendering optimization, not a way to remove markup, reduce network transfer, or avoid JavaScript execution in general. See MDN’s content-visibility reference and web.dev’s explanation.

The technique is most useful when a page has large, independent chunks whose contents are expensive to render. Applying it to every small element can add complexity without skipping much work. Start with article sections, product detail groups, or other substantial blocks below the initial viewport.

2. Apply it to substantial sections

Wrap meaningful chunks in elements, then use content-visibility: auto and a fallback intrinsic size:

<article class="long-article">
  <section class="article-section">
    <h2>Introduction</h2>
    <p>This section is initially visible.</p>
  </section>

  <section class="article-section">
    <h2>A later section</h2>
    <p>The browser may defer rendering this section while it is offscreen.</p>
  </section>
</article>
.article-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

contain-intrinsic-size supplies a placeholder size while size containment is active. In auto 500px, the browser can use a remembered rendered size when available and use 500px as the fallback otherwise. The value is an example, not a universal recommendation. Choose a fallback that approximates the section’s normal size for your content and layout. See MDN’s contain-intrinsic-size reference.

Choose the right boundaries and fallback

  • Use sections with content that can render independently. A section should not rely on rendering another skipped section to determine its own presentation.
  • Begin with blocks below the fold. Applying the property to the initial viewport is less likely to defer useful work.
  • Estimate a typical block height for the fallback, then inspect pages with short, long, and unusually sparse sections.
  • Check scroll position and layout as skipped blocks become rendered. A poor estimate can make the page appear to shift when the actual size replaces the placeholder.
  • Keep essential content in the markup. The property defers rendering; it does not remove the content or make it a substitute for optimizing large assets, scripts, or network requests.

3. Understand containment, accessibility, and interaction

When the browser skips an auto section, its contents are not painted, and skipped content does not receive pointer events. The browser applies layout, style, paint, and size containment to skipped contents. As the section becomes relevant, the browser renders it. The auto value differs from hidden; do not swap them as if they had the same behavior. MDN describes these details in its CSS containment guide.

Skipped content remains in the DOM and accessibility tree. It can remain available to search and focus navigation. There is an accessibility nuance: descendant styles are not rendered while the section is skipped, so descendants that are meant to be excluded with display: none or visibility: hidden may still appear in the accessibility tree before the section becomes relevant. If content must be absent from that tree, use aria-hidden="true" only when that matches the intended semantics, and verify the behavior with assistive technology.

JavaScript that reads layout or other DOM state in ways that force a skipped subtree to render can undermine the optimization. Audit code that measures descendants or depends on their rendered state, and check browser performance diagnostics when the expected work is not skipped.

Pause expensive work in skipped sections

For elements using content-visibility: auto, the contentvisibilityautostatechange event can tell application code when the browser starts or stops skipping an element. This is useful for work such as drawing into a canvas that does not need to run while its section is skipped. A minimal example:

const section = document.querySelector(".chart-section");

section.addEventListener("contentvisibilityautostatechange", (event) => {
  if (event.skipped) {
    stopCanvasUpdates();
  } else {
    startCanvasUpdates();
  }
});

Define stopCanvasUpdates and startCanvasUpdates for the application, and handle the case where the section is missing before adding the listener. Use this event to control work that is safe to pause; do not use it to remove content that users or assistive technology need.

4. Measure the actual rendering improvement

Compare representative pages before and after the change. Look at initial rendering and interaction cost, how much expensive offscreen content exists, layout stability as sections render, and behavior on the browsers and devices in your support matrix. Test pages with different content lengths and complexity, and check both a fresh visit and a visit where content may already have rendered.

web.dev reported a 7x initial-load rendering performance boost in its own demonstration after applying content-visibility: auto to chunked content areas. That result describes the demo, not a general forecast for another site. Actual gains depend on the work the browser can skip and whether application code forces skipped content to render. The article’s demo is useful context, but only measurement on your page can establish its result.

Include a visual review as well as performance measurements. Confirm that reserved space is plausible, scrolling remains predictable as blocks render, interactive controls work when a section becomes relevant, and assistive technology exposes the intended content.

5. Browser support and progressive use

MDN labels content-visibility Baseline Newly available since September 2024. web.dev’s later announcement says support reached all three major browser engines on September 15, 2025. Broad current support does not guarantee support in older browser versions or devices, so check the compatibility data against your audience before relying on this behavior. See MDN’s browser compatibility data and web.dev’s Baseline announcement.

Because this property is an enhancement, unsupported browsers can still render the ordinary content. Verify that the unoptimized layout is usable and that your page does not depend on the skipped-state behavior for correctness.

6. Troubleshooting common problems

Symptom Likely cause What to do
Little or no performance improvement The skipped sections are small or cheap to render, are already visible, or scripts force their rendering. Apply the property to larger offscreen chunks. Inspect code that measures or otherwise forces rendering of descendant content, then compare performance again.
Large scroll jumps or unstable spacing The fallback intrinsic size poorly represents the real section size. Tune the fallback using representative sections. Test varied content lengths and observe the page as sections render.
A control in a skipped section does not respond to a pointer The section is still skipped, and skipped content does not receive pointer events. Check whether the section has become relevant and rendered before expecting pointer interaction. Review the page’s scrolling and layout context.
Hidden content is exposed to a screen reader Descendant styles such as display: none or visibility: hidden may not have taken effect while the section is skipped. If the content should be absent from the accessibility tree, apply aria-hidden="true" where semantically appropriate and verify with assistive technology.
Canvas or another ongoing task keeps using resources Application work continues even though the browser is skipping rendering for the section. Use contentvisibilityautostatechange to pause and resume safe-to-pause work as the skipped state changes.
Behavior differs on an older client The browser version may not support the property. Check browser compatibility for your supported audience and confirm the ordinary page remains usable without the optimization.

7. Performance, reliability, and cost notes

  • Performance: the opportunity is deferred layout and painting for substantial offscreen content. It does not generally eliminate DOM creation, network transfer, or application JavaScript work.
  • Reliability: keep content correct when the optimization is unsupported, and test focus, search, pointer interaction, scrolling, and assistive technology with skipped sections.
  • Layout: intrinsic-size fallbacks trade an estimate for less initial work. A poor estimate can make the rendered page’s size differ from the reserved space.
  • Cost: the CSS property has no per-use product cost. Engineering effort is in selecting section boundaries, auditing code that forces rendering, and measuring results across representative devices.

8. Capture before-and-after screenshots

Visual comparisons can help catch spacing changes as skipped sections render. For repeatable captures across URLs or viewport sizes, ScreenshotNeo is a website screenshot API and MCP server for developers. It can capture a full page or a selected element, use device presets or custom viewports, and apply custom CSS or JavaScript. See the ScreenshotNeo documentation for its API options.

For a quick capture, request an image from a URL. Use a page and viewport setup that make the rendering state you want to inspect reproducible; a screenshot alone does not establish performance or accessibility behavior.

Or skip the browser setup

One GET request can return a screenshot. Replace YOUR_API_KEY and the target URL with your values. See the ScreenshotNeo documentation for configuration options.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
  • Cookie and consent banners are accepted like a visitor, and 60+ known consent platforms, newsletter popups, and chat widgets are removed before the shot. Each step can be turned off.
  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers report the page verdict and billing status.
  • An MCP server gives AI agents, including Claude, Cursor, and other MCP clients, the take_screenshot, get_page_info, and capture_pdf tools.
  • The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is available on every plan.

Sign up for 1,000 free screenshots a month, with no card required.

9. FAQ

Does content-visibility hide offscreen content from the DOM?

No. It can defer rendering while leaving the content in the DOM and accessibility tree.

Should I apply it to every element on a long page?

Usually start with substantial, independent sections. Tiny elements may not contain enough rendering work to make the added containment useful.

Is the web.dev 7x result typical?

It is a result from web.dev’s demonstration, not a general expected improvement. Measure your own pages and supported devices.

Does it replace lazy loading images?

No. It targets rendering work; it is not a general substitute for controlling network transfer or image loading.