perf(PageLayout): eliminate per-frame React renders during window resize#7847
Draft
Copilot wants to merge 3 commits into
Draft
perf(PageLayout): eliminate per-frame React renders during window resize#7847Copilot wants to merge 3 commits into
Copilot wants to merge 3 commits into
Conversation
🦋 Changeset detectedLatest commit: 850638b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
…PaneWidth Split syncAll() into syncDom() (DOM/refs/ARIA, called each rAF frame) and commitToReact() (single startTransition at gesture end). Replace the Date.now() throttle + rAF fallback with a single rAF coalesce — rAF already guarantees at most one call per frame, and the throttle was the source of double-fire on bursty input. The debounce callback now also calls syncDom() for a guaranteed final frame and commitToReact() for the one React commit per gesture. Add pendingMaxRef / pendingClampedRef to carry values across frames into the commit. Update test descriptions and add a new assertion that verifies zero startTransition calls during resize frames and exactly one at gesture end. Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
…TimeAsync(149/1) split Use 149ms advance (flushes rAF, misses debounce) + 1ms advance (fires debounce) to clearly prove zero startTransition calls during resize and exactly one at end. Removes the nonexistent vi.runAllImmediateAsync optional-chaining guard. Co-authored-by: mattcosta7 <8616962+mattcosta7@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix lag in PageLayout pane updates during quick window resizing
perf(PageLayout): eliminate per-frame React renders during window resize
May 18, 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.
During fast window resizing,
usePaneWidthcalledstartTransition(setState)on every throttled tick (~60 fps), stacking render requests that caused the pane DOM to visually "catch up" after the gesture ended.What changed
packages/react/src/PageLayout/usePaneWidth.tssyncAll()into two functions:syncDom()— mutates CSS custom properties (--pane-max-width,--pane-width), clampscurrentWidthRef, and updates ARIA attributes via direct DOM manipulation. Zero React state changes.commitToReact()— called exactly once at gesture end; flushes pending values into React state viastartTransitiononly if they actually changed.Date.now()throttle + rAF-fallback pattern (which could firesyncAlltwice per frame on bursty input) with a singlerequestAnimationFramecoalesce: if a rAF is already pending, new resize events are dropped until it fires.syncDom()(guaranteed final-frame sync) →commitToReact()(the one React commit for the whole gesture) →endResizeOptimizations().pendingMaxRef/pendingClampedRefto carry values across frames into the commit.packages/react/src/PageLayout/usePaneWidth.test.tsstartTransitionis called zero times while resize events are firing (pre-debounce) and exactly once when the gesture ends.Rollout strategy
Testing & Reviewing
The key behavioral invariants are unchanged —
--pane-max-width/--pane-widthCSS variables and ARIA attributes continue to track the viewport in real time; only the React state commit is deferred. The new test exercises the zero-renders-during-gesture / one-commit-at-end contract directly.Custom widths with
constrainToViewport === falsestill bail out of the resize listener early (untouched). The drag-handle path is untouched.Merge checklist