Excessive DOM size in Svelte
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
DOM has 1500 nodes
To your coding agent · MCP
agent › get_detected_issues
→ { detector: "dom-bloat", issue: "DOM has 1500 nodes", threshold: "≥ 800 nodes (warning), ≥ 1,500 nodes (error) — sampled every 5s" }
The same string in your widget and in your agent’s context — no screenshot, no copy-paste.
Root causes
The fix for Svelte
Use @tanstack/svelte-virtual, or a Svelte-native virtual list, to keep only visible rows mounted.
<script lang="ts">
import { createVirtualizer } from '@tanstack/svelte-virtual'
let parentRef: HTMLElement
const virtualizer = createVirtualizer({
count: items.length,
getScrollElement: () => parentRef,
estimateSize: () => 40,
})
</script>Steps
- 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
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.