Skip to content

fix(Graph): auto-park physics loop when layout settles (0.5.15)#319

Merged
I-am-nothing merged 1 commit into
mainfrom
fix/graph-autostop-settle
Jun 24, 2026
Merged

fix(Graph): auto-park physics loop when layout settles (0.5.15)#319
I-am-nothing merged 1 commit into
mainfrom
fix/graph-autostop-settle

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

What

The force-directed Graph's requestAnimationFrame loop ran forever — every frame re-ran the O(n²) force step and re-reconciled the whole SVG (every <line>/<circle>/<text>), for the life of the page, with no settle/convergence cutoff (damping only multiplies velocity by 0.85, never zeroes it). Mount several graphs on one page and they all churn the main thread indefinitely; cold-starting three of them on a single scroll frame is what makes scrolling into a multi-graph section lag.

This adds a settled park: the loop skips the step + re-render once every revealed, unpinned node is below a sub-pixel velocity threshold (SETTLE_V2, ≈0.05 px/frame) and nothing is driving motion. It re-arms within one frame from each motion source — rebuildSim (mount/reseed/replay), ResizeObserver, startReveal, and node pointerdown. A parked loop keeps an empty rAF scheduled rather than cancelling, so there's no missed-wake risk at ~0 idle cost.

The settle check runs after step(), so a just-released node (velocity 0 at release, force applied that frame) keeps the loop awake until it actually comes to rest — nothing freezes mid-air.

Intent preserved (no API change)

The live force-directed settle look, the BFS reveal (still replays on replay()), and node dragging are all unchanged. meta.description now documents the auto-pause so consumers aren't surprised.

Versioning

Patch bump 0.5.14 → 0.5.15 + CHANGELOG entry, in this PR (release label).

Considered & deferred (not in this PR)

  • autoStop prop / paused control — an opt-out for a consumer that wants a perpetually-jittering ambient graph. Default-on is what every current consumer wants; can add on request.
  • Funnel wakes through one chokepoint (wake-on-revealed-set-write). The current wake sites are covered in practice (pointerdown precedes drag-move; the revealTimer guard holds the loop awake through playback), so this is hardening, not a fix.

Verification

tsc build clean; validated live on the landing fan-out (three graphs) — graphs still settle into clusters, reveal replays on scroll, drag works, and idle graphs stop churning.

🤖 Generated with Claude Code

The force-directed Graph's requestAnimationFrame loop ran forever — every
frame re-ran the O(n²) force step AND re-reconciled the whole SVG, for the
life of the page, even after the layout had visibly stopped moving. Three
graphs mounted on one page (the landing fan-out) cold-start their sims on a
single scroll frame and then never idle, which is what makes scrolling into
that section lag.

It now parks itself once every revealed, unpinned node falls below a
sub-pixel velocity threshold and nothing is driving motion, and re-arms
within a frame on drag, replay/reseed, or resize (a parked loop keeps an
empty rAF scheduled, so there's no missed-wake risk). An idle graph costs no
per-frame work.

No API change; the settle look, BFS reveal (replays on replay()), and node
dragging are all unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing added the release Trigger a version bump on merge label Jun 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Storybook Preview: https://mirrorstack-ai.github.io/web-ui-kit/pr/319/

github-actions Bot added a commit that referenced this pull request Jun 24, 2026
@I-am-nothing I-am-nothing merged commit 30118ea into main Jun 24, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in MirrorStack Platform Jun 24, 2026
github-actions Bot added a commit that referenced this pull request Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Trigger a version bump on merge

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant