Skip to content

Batch descendant registry updates outside effect commits - #8612

Open
alexus37 wants to merge 3 commits into
mainfrom
agents/batching-descendant-registry-updates
Open

alexus37 wants to merge 3 commits into
mainfrom
agents/batching-descendant-registry-updates

Conversation

@alexus37

Copy link
Copy Markdown

Closes #8606

Moves descendant registry state publication onto a shared deferred scheduler. Registration rebuilds, value changes, and cleanup now update one authoritative snapshot so rapid lifecycle changes coalesce without stale descendants, lost updates, or ordering regressions.

Adds stress coverage for rapid mount, update, unmount, unregister, remount, and reorder sequences, including render-count assertions for batched publication.

Changelog

New

None.

Changed

  • Descendant registries publish batched state updates after effect commits while preserving item order and current metadata.

Removed

None.

Rollout strategy

  • No changes needed in github/github-ui
  • Needs changes in github/github-ui
  • Ships with feature flag(s)
  • Not sure
  • None

Testing & Reviewing

  • npm test -- packages/react/src/utils/__tests__/descendant-registry.test.tsx --run — passed (11 tests)
  • npm run build — passed
  • npm run type-check — passed
  • npm run lint — passed
  • npm run lint:css — passed
  • npm run format:diff — passed
  • CI=true npm test — passed (160 files, 2,902 tests; 3 skipped, 10 todo)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@changeset-bot

changeset-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f97853f

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

This PR includes changesets to release 1 package
Name Type
@primer/react 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

@github-actions github-actions Bot added the integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm label Oct 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Action required

👋 Hi, this pull request contains changes to the source code that github/github-ui depends on. If you are GitHub staff, test these changes with github/github-ui using the integration workflow. Check the integration testing docs for step-by-step instructions. Or, apply the integration-tests: skipped manually label to skip these checks.

@primer

primer Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

🤖 Lint issues have been automatically fixed and committed to this PR.

Capture test state setters from effects instead of mutating outer bindings during render.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
github-actions Bot temporarily deployed to storybook-preview-8612 October 22, 2026 16:54 Inactive
@github-actions github-actions Bot added integration-tests: failing Changes in this PR cause breaking changes in gh/gh and removed integration-tests: recommended This change needs to be tested for breaking changes. See https://arc.net/l/quote/tdmpakpm labels Oct 23, 2026
@broccolinisoup

Copy link
Copy Markdown
Member

Hello Primer 👋🏻 This PR is a part of our performance improvement epic and we would appreciate your review 🙏🏻

I've tested each Storybook scenario and haven't identified any unexpected behaviour. I also asked 🤖 to profile main against this PR's branch; the results are below.

We aren't expecting noticeable performance gains from this PR alone. However, we expect the cumulative reduction in unnecessary rendering across all the related sub-issues to have a positive impact on overall performance.

Rendering comparison — before vs. after

Profiled ActionBar and UnderlineNav with three runs per component on each branch.

Scenario: mount wide → narrow → wide → narrow → open overflow menu.

Component Rendering metric Before (main) After (PR #8612) Change
ActionBar Observed component render passes during mount 3 2 1 fewer · 33%
UnderlineNav Observed component render passes during mount 3 2 1 fewer · 33%
ActionBar Total story-root commits 17–18 17–18 Unchanged
UnderlineNav Total story-root commits 17–18 16–17 1 fewer per run
Both Commits per width change 2 2 Unchanged
Both Long tasks during the scenario (>50 ms) 0 0 Unchanged

Result: Both components showed one fewer render pass during mount, consistently across all three runs. Ordinary resizing showed no further render-count reduction. Overflow contents and ordering matched on both branches.

@broccolinisoup
broccolinisoup marked this pull request as ready for review October 23, 2026 10:30
@broccolinisoup
broccolinisoup requested a review from a team as a code owner October 23, 2026 10:31
@broccolinisoup
broccolinisoup requested review from llastflowers and a balanced review from Copilot October 23, 2026 10:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

An intervening Provider commit can cancel a required rebuild and leave mounted descendants missing from the registry.

1 open issue
What changed in this PR

Addresses #8606 by deferring descendant registry publication until after effects, aiming to reduce cascading renders while preserving item order and metadata.

Changes:

  • Uses a shared scheduler and authoritative snapshot to batch registry updates.
  • Adds lifecycle stress tests and render-count assertions.
  • Includes a patch changeset for ActionBar and UnderlineNav.
File Description
packages/​react/​src/​utils/​descendant-registry.tsx Defers and coalesces registry rebuilds and publication.
packages/​react/​src/​utils/​__tests__/​descendant-registry.test.tsx Adds asynchronous assertions and rapid lifecycle coverage.
.changeset/​batch-descendant-registry-updates.md Documents the consumer-facing batching improvement.

Review effort: Balanced

Comment on lines +96 to +99
if (workingRegistryRef.current === 'queued') {
rebuildRegistry()
} else if (workingRegistryRef.current === 'idle') {
setRegistry(new Map(registryRef.current))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a valid call-out—wondering if this has been investigated? A test that covers this case sounds like a good idea too!

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 23a42dde-c59d-4f5a-97ca-4fa6f7c41164
@primer-integration

Copy link
Copy Markdown

Integration test results from github/github-ui PR:

Passed  Changes   Passed
Passed  CI   Passed
Passed  VRT   Passed
Passed  Projects   Passed

All checks passed!

@github-actions github-actions Bot added integration-tests: passing Changes in this PR do NOT cause breaking changes in gh/gh and removed integration-tests: failing Changes in this PR cause breaking changes in gh/gh labels Oct 23, 2026

This branch was successfully deployed

2 active deployments
storybook-preview-8612 — f97853fc Deployed Oct 23, 2026 by github-actions[bot]
github-pages — f97853fc Deployed Oct 23, 2026 by alexus37 via deploy-preview #33878
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration-tests: passing Changes in this PR do NOT cause breaking changes in gh/gh

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Descendant registry publishes state during effect commit

4 participants