The hidden cost of long pages

Open a page with 500 table rows or 300 feed cards. The browser computes styles for every element, runs layout to calculate positions, and paints everything — even the parts you'll never scroll to. That's real work on the main thread, and it delays interactive time.

Google measured a 7× faster rendering time on a news page after applying content-visibility to article cards. That's not incremental. On a slow device, it's the difference between "loaded" and "still loading."

The two-line fix

.feed-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 300px;
}

That's the entire implementation. The browser groups each .feed-card into a containment context. For any card not near the viewport, it skips layout and paint completely. When you scroll toward it, the browser renders it before it enters view. When you scroll past it, the browser can discard the paint and reclaim memory.

Why contain-intrinsic-size is not optional

When the browser skips layout for an off-screen element, it doesn't know how tall it is. Without a size, the element collapses to zero height. A page with 500 collapsed elements gets a wrong scrollbar, and scroll position jumps around as elements render in — the classic "why does the page keep moving" experience.

contain-intrinsic-size: auto 300px; gives the browser a placeholder size. The auto keyword matters: after the browser renders an element for the first time, it remembers the actual height and uses that for future off-screen cycles. The 300px is just the initial estimate. Without auto, the browser always uses the hint value and never updates it, breaking variable-height elements permanently.

What it does NOT break

A common concern: if the browser skips rendering, does accessibility, keyboard navigation, or find-in-page break?

It does not. The browser maintains the DOM and the accessibility tree regardless of content-visibility. Ctrl+F finds text inside skipped elements and scrolls them into view, triggering rendering on the way. Pressing Tab to reach a focusable element inside a skipped container triggers immediate rendering for that container. Screen readers traverse the DOM, not the render tree — off-screen elements are still accessible.

The only thing content-visibility: auto skips is visual rendering work: layout, paint, and compositing. The element is off-screen, not absent.

Where to apply it — and where not to

The property shines on repeating elements with clear boundaries: feed cards, table rows, comment threads, list items, documentation sections. If the element is one of many similar elements stacked vertically, and most are off-screen at load time, it's a strong candidate.

.comment {
  content-visibility: auto;
  contain-intrinsic-size: auto 80px;
}

.data-row {
  content-visibility: auto;
  contain-intrinsic-size: auto 48px;
}

.article-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 400px;
}

Don't apply it to elements that need to report their size at load time — sticky headers, elements measured in JavaScript with getBoundingClientRect() before scroll, or anything in a layout that depends on all children being fully laid out simultaneously. For those, the browser's skip means the measurement returns zero and the calculation breaks.

Browser support

content-visibility is Baseline 2024: Chrome 85 (August 2020), Firefox 125 (April 2024), Safari 18.0 (September 2024). Safari completing the set in late 2024 made it safe for production without fallbacks, assuming a modern browser baseline. For older Safari, the property is silently ignored — the page renders normally, just without the optimization.

How to verify the impact

Open DevTools on your longest page, run a Performance recording during load, and look at the "Layout" and "Paint" entries on the main thread. If they're wide and the page is slow to become interactive, content-visibility: auto on the repeating elements is often the fastest fix available — one CSS property that can halve rendering time on data-heavy pages. Add contain-intrinsic-size: auto alongside it to keep the scrollbar accurate, and the change is production-safe with no other modifications required.

The author provides an interactive playground with 500 cards and a live timer for side-by-side comparison. Try it: run both buttons and watch the numbers.

Next steps

  • Identify your repeating off-screen elements.
  • Add content-visibility: auto with a sensible contain-intrinsic-size.
  • Measure the performance delta in DevTools.
  • Deploy and monitor for any layout shifts.

The property is supported in all modern browsers as of late 2024. There's no reason not to use it on long pages today.