A new benchmark from Raxxo Studios on DEV.to puts hard numbers on content-visibility: auto, showing that while it can slash first frame time from 144 ms to 38 ms on a 3,000-card grid, using it without contain-intrinsic-size creates a performance trap that renders 444 cards instead of 16.

The Benchmark: Chromium 145 on M3 Pro

The test ran 3,000 product cards through headless Chromium 145 on an M3 Pro laptop, with viewport set to 1280x800. Four variants were compared using Playwright, with 15 runs per variant to establish medians. Variant D, which paired content-visibility: auto with a measured contain-intrinsic-size: auto 580px, achieved a first frame time of 38.1 ms and rendered only 16 cards initially. In contrast, Variant B, the common snippet using content-visibility: auto alone, took 52.9 ms to the first frame but rendered 444 cards because skipped elements were treated as zero-height, causing massive layout thrashing.

Why Snippets Break Small Pages

The study reveals a critical pitfall for smaller grids. At 200 cards, the naive implementation (Variant B) actually made the page slower than doing nothing (Variant A), clocking in at 16.8 ms versus 14.4 ms for first frame time. It wasn't until the page size hit 1,000 cards that the naive snippet began to show a net benefit. For pages under 200 items, the overhead of the second layout pass outweighs the savings from skipping initial rendering. This suggests that adding content-visibility to standard e-commerce grids without proper sizing hints can actively degrade performance.

The Height Guessing Game

Accurate height estimation is non-negotiable. Variant C used a guessed height of 360 px, while the real cards averaged 583 px. This discrepancy caused the page height to be 36 percent too short, breaking scroll restoration. When the test scrolled to card 2,400 and saved the window.scrollY offset, Variant C clamped the scroll position, landing the user on card 2,992 instead. Variant D, using the accurate 580 px guess, landed within one row of the target. The author recommends measuring card heights at specific breakpoints using getBoundingClientRect().height and using media queries to apply the correct contain-intrinsic-size.

Layout Work Moves to Scroll Time

While content-visibility defers layout work, it doesn't eliminate it. Variant D spent 1,646 ms on layout during a full scroll of the page, spread across 560 scroll steps (approx. 3 ms per step). This deferred work generally fits within the 16.6 ms frame budget of a 60 Hz display, keeping interactions smooth. However, this is not a fix for Interaction to Next Paint (INP) issues caused by JavaScript; the author notes that on real Shopify stores, INP did not improve because the bottlenecks were in interaction handlers, not rendering.

Key Takeaways

  • Never use content-visibility: auto without contain-intrinsic-size: auto and a measured height; otherwise, you risk rendering 444 cards instead of 16.
  • For pages with fewer than 200 repeated items, the property may slow down the initial load compared to no optimization.
  • Scroll restoration based on window.scrollY breaks if the initial page height estimate is wrong; use scrollIntoView with element IDs instead.
  • The property is supported in Chrome/Edge 85+, Firefox 125+, and Safari 18+, with graceful degradation in older browsers.

The Bottom Line

Stop copying the one-liner snippet. If you are building a long feed, measure your card heights at your smallest and largest breakpoints and pair content-visibility with precise intrinsic sizing, or you are just trading fast loads for broken scrollbars.