Skip to content

perf(system): reduce pan-on-scroll gesture work - #5884

Open
AlaricBaraou wants to merge 2 commits into
xyflow:mainfrom
AlaricBaraou:perf/wheel-gesture-hot-path
Open

perf(system): reduce pan-on-scroll gesture work#5884
AlaricBaraou wants to merge 2 commits into
xyflow:mainfrom
AlaricBaraou:perf/wheel-gesture-hot-path

Conversation

@AlaricBaraou

@AlaricBaraou AlaricBaraou commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

When panOnScroll is enabled, wheel gestures previously repeated avoidable native work on every event:

  • the manual pinch path used d3-selection's pointer, which read the pane's bounding rect on every ctrl-wheel tick;
  • d3 emitted an end event for every pinch scaleTo, making xyflow clear and recreate its trailing onPanZoomEnd timer on every tick;
  • the direct scroll-pan path independently cleared and recreated its own trailing end timer on every tick.

This change caches the pane origin for each 150 ms pinch gesture and coalesces both end paths with deadline-based trailing timers. The latest event and viewport are still delivered once, 150 ms after the final tick. D3 end state remains private per pan/zoom instance in a WeakMap.

Measurement

Call-count probes over the real handlers produced:

Operation during a 100-event gesture Before After
Pinch pane rect reads 100 1
Pinch/D3 end timer sets before idle 100 1
Pinch/D3 end timer clears 100 0
Direct pan end timer sets before idle 100 1
Direct pan end timer clears 100 0
End callbacks 1 1

A timer wakes and re-arms against the latest deadline during a long gesture. Pointer coordinates and the final viewport were unchanged, and a new gesture after the idle window gets a fresh timer and remeasures the pane origin.

This was motivated by a production profile where the pinch path's repeated pane reads and timer churn accounted for about 308 ms of main-thread self time across a slow zoom gesture. The direct pan timer improvement is a follow-up found during downstream review; it was not part of that 308 ms measurement.

Validation

  • pnpm --filter @xyflow/system typecheck
  • ESLint and Prettier on the changed files
  • pnpm --filter @xyflow/system build
  • React pane Playwright suite in Chromium: 8/8 passed
  • Browser timer probe: two 100-event pan gestures produced one timer per gesture and zero clears

The package-wide lint command also reports two existing no-unnecessary-type-assertion errors in src/utils/edges/positions.ts on unmodified main.

@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 269b7f1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@xyflow/system Patch
@xyflow/react Patch
@xyflow/svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@AlaricBaraou AlaricBaraou changed the title perf(system): reduce pan-scroll pinch gesture work perf(system): reduce pan-on-scroll gesture work Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant