Perf S1: size-gate continuous node effects on dense graphs (idle FPS 6.7→60)#68
Merged
Merged
Conversation
… FPS 6.7→60) Large graphs collapsed to ~7 idle FPS at HIGH quality while sitting still. Root cause (measured): every node's .node-bg carries an SVG drop-shadow halo and the living-graph animations (node-breathe / node-ache / edge-flow) run continuously, so ~1000 filtered layers repaint every frame. LOW tier already strips these and hits 60 idle FPS on the IDENTICAL DOM — proving the effects, not the node count, were the idle killer. Fix: gate those same effects off by graph SIZE, independent of the quality tier. A graph with > DENSE_GRAPH_NODE_THRESHOLD (150) nodes sets data-dense on .graph-container; new CSS rules (mirroring the LOW strips) drop the animations and the drop-shadow filter. Small graphs keep the full living-graph aesthetic at any tier — a user who picks HIGH still gets pretty small graphs and fast big ones. Measured on the Compute Core example (1000 nodes / 1400 edges), HIGH quality: idle FPS 6.7 → 59.7 (filter/blur elements 1166 → 166) Drag (1.2) and zoom (3.2) are per-tick work, addressed in following stages. Adds tests/diagnostics/large-graph-profile.spec.ts (report-only baseline: idle/drag/zoom FPS + DOM weight + data-dense confirmation). Verified: web typecheck 0 errors; living-graph e2e 3/3 (small-graph effects intact); THE GATE 5/5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🧪 Comprehensive Test Suite
Full-stack smoke gate runs in the CI workflow. |
This was referenced Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 1 of a measured, multi-stage large-graph performance effort
The Compute Core example graph (1000 nodes) felt sluggish. Profiling
(
tests/diagnostics/large-graph-profile.spec.ts, new here) found it was 6.7idle FPS at HIGH quality — while nothing was moving.
Root cause (measured, not guessed)
Every node's
.node-bgcarries an SVGurl(#node-drop-shadow)halo, and theliving-graph animations (
node-breathe/node-ache/edge-flow) runcontinuously. At 1000 nodes that's ~1000 filtered layers repainting every
frame. The LOW quality tier already strips these and hits 60 idle FPS on the
identical DOM — so the effects, not the element count, were the idle killer.
Fix
Gate those effects off by graph size, independent of the quality tier: above
DENSE_GRAPH_NODE_THRESHOLD(150) nodes,.graph-containergetsdata-dense,and new CSS (mirroring the existing LOW strips) drops the animations + drop-shadow
filter. Small graphs keep the full living-graph aesthetic at any tier.
Result (Compute Core, 1000n/1400e, HIGH)
Drag (1.2) and zoom (3.2) FPS are per-tick work — addressed in the next stages
(viewport culling, zoom-handler throttle, simplified nodes at scale, spacing).
Verification
living-graphe2e 3/3 — small-graph effects unchangedtest:smoke) 5/5🤖 Generated with Claude Code