Excessive DOM size
Every DOM node the browser has to style, lay out, and keep in memory costs time on each frame, so a page with thousands of nodes feels sluggish to scroll and slow to interact with. AI agents produce this constantly: they map over data without virtualization, wrap everything in defensive <div>s, and render hidden content with display:none instead of not rendering it. The result passes review because it looks right — it just quietly janks.
Symptoms
How VibeCheck catches it
In your widget · Problems
To your coding agent · MCP
The same string in your widget and in your agent’s context — no screenshot, no copy-paste.
Root causes
The fix
Only render what is on screen. Virtualize long lists so the DOM holds a small window of rows, flatten unnecessary wrapper elements using CSS grid/flex, and conditionally mount content instead of hiding it. As a cheap first win, add CSS content-visibility:auto to offscreen sections so the browser skips their layout.
- Find the largest list or repeated subtree (VibeCheck reports the heaviest selector)
- Virtualize it so only visible rows are in the DOM
- Remove redundant wrapper elements and replace
display:nonewith conditional rendering
.section {
content-visibility: auto;
contain-intrinsic-size: 0 500px; /* reserve space to avoid scroll jump */
}FAQ
- How many DOM nodes is too many?
- Lighthouse warns past ~800 and errors past ~1,500 nodes in one document — the same thresholds VibeCheck uses. Under ~800 is comfortable; the exact number matters less than avoiding unbounded lists.
- Does hiding elements with
display:nonereduce DOM size? - No. Hidden elements are still in the DOM and still cost memory and (for some operations) layout. Conditionally render them instead so they aren’t created until needed.
- Will
content-visibilityfix it on its own? - It skips rendering work for offscreen sections, which is a big, cheap win — but the nodes still exist. For truly large lists (thousands of rows) you still need virtualization.