Perf S3: simplified-node LOD when zoomed out (whole-graph zoom FPS 3.5→10)#70
Merged
Merged
Conversation
…5→10) In the whole-graph "fit" view (scale ~0.1) every node's ~40 SVG sub-elements are on screen and painted each frame, and the per-tick edge pass positions 1400 arrows + labels — even though none of it is legible at that zoom. That's what makes looking at the entire graph sluggish. Add a simplified LOD: on a dense graph below SIMPLIFY_SCALE (0.45) the container gets data-simplify, and CSS hides per-node detail (title bar, type/title/desc text, status & priority bars/icons/labels, edit/relationship/descend icons) plus arrows and edge labels outright (display:none — opacity:0 still paints). Each node renders as just its colored card; edges stay so structure is legible. updateEdgePositions also skips the now-hidden arrow + label positioning per tick (via simplifiedRef), removing the bulk of the remaining per-tick cost. Zooming back in past the threshold restores full detail (and the one-shot settle pass still runs so labels are correct when shown). Measured (Compute Core, 1000n/1400e, HIGH), whole-graph fit view: zoom FPS 3.5 → 10.5 (paintedDetail 4000 → 0) drag FPS 1.2 → 4.4 idle FPS 60 → 60 (S1 preserved) Numbers are from a SERIAL profiler run (--workers=1); running the two quality tests in parallel thrashed the CPU and produced contradictory FPS — the spec is now mode:'serial'. Verified: web typecheck 0; THE GATE 5/5; node-inspector green (zoomed-in detail restores correctly). 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.
Next stage of the measured large-graph perf effort (follows #68, #69)
This targets the FPS you feel looking at the whole graph. At the fit view
(scale ~0.1) every node's ~40 SVG sub-elements are painted each frame and the
per-tick edge pass positions 1400 arrows + labels — none of it legible at that
zoom.
Change
On a dense graph below scale 0.45,
.graph-containergetsdata-simplifyand CSS hides per-node detail (text, status/priority bars, icons) plus arrows and
edge labels via
display:none(opacity:0still paints!). Each node becomes justits colored card; edges stay so structure reads.
updateEdgePositionsalsoskips the hidden arrow/label positioning per tick. Zooming in past the threshold
restores full detail (the one-shot settle pass still runs so labels are correct).
Result (Compute Core, 1000n/1400e, HIGH — whole-graph fit view)
Measurement honesty
Numbers are from a serial profiler run (
--workers=1). Running the twoquality tests in parallel thrashed the CPU and gave contradictory FPS (LOW 59 /
HIGH 2 on identical DOM) — the spec is now
mode:'serial'to prevent that.Single-node drag of the whole graph (4.4) is still bound by the force sim +
1000 node/1400 edge per-tick updates; a further stage can throttle the
zoom/pan handler and simplify edge geometry. Idle, zoom, and zoomed-in
interaction are now the big wins.
Verification
node-inspectorgreen — zoomed-in detail restores correctly🤖 Generated with Claude Code