Skip to content

demo(benchmark-react): replace react-window with renderLimit#3803

Merged
ntucker merged 1 commit intomasterfrom
bench-react-render-limit
Mar 21, 2026
Merged

demo(benchmark-react): replace react-window with renderLimit#3803
ntucker merged 1 commit intomasterfrom
bench-react-render-limit

Conversation

@ntucker
Copy link
Copy Markdown
Collaborator

@ntucker ntucker commented Mar 21, 2026

Motivation

The react-window virtualized list renders rows by index, which forces React to re-render every visible row on insert/delete. It also couples the DOM size to the store size—changing mountCount directly changes how many DOM nodes exist, conflating store throughput with rendering cost.

Solution

  • Drop react-window and replace all <List> usages with PlainIssueList, a plain keyed list. React can now reconcile by key, skipping unchanged rows on insert/delete.
  • Add renderLimit — a per-scenario cap on how many items render to the DOM, while the store still holds the full dataset. This decouples store size from DOM pressure and makes update scenarios (update-entity, update-user, ref-stability) measure store propagation rather than rendering cost.
  • Rename scenarios for clarity and consistency:
    • update-single-entityupdate-entity
    • update-shared-user-500-mountedupdate-user (now 1000 items)
    • update-shared-user-10000-mountedupdate-user-10000
    • sorted-view-mount-500getlist-500-sorted
    • sorted-view-update-entityupdate-entity-sorted
  • Increase default mountCount from 100/500 to 1000 for update and ref-stability scenarios, with renderLimit: 100 to keep DOM size constant.
  • Make React Compiler the default build. The .babelrc.js now enables it unless REACT_COMPILER=false. README instructions updated to document the opt-out path.

Open questions

N/A

Made with Cursor


Note

Medium Risk
Benchmark behavior and scenario definitions change substantially, which can shift CI perf baselines and potentially introduce measurement flakiness, but this is isolated to the examples/benchmark-react tooling/docs.

Overview
React benchmark scenarios are redefined to decouple store size from DOM size. The suite removes react-window virtualization in favor of a keyed PlainIssueList, and introduces a per-scenario renderLimit that caps rendered rows while still mounting larger datasets in the store.

Runner/scenario plumbing is updated accordingly. bench/scenarios.ts renames and retunes several hot-path scenarios (including new sorted variants), increases default mountCount (often to 1000/10000) while applying renderLimit: 100, and bench/runner.ts now calls window.__BENCH__.setRenderLimit() when configured.

Build/usage defaults shift toward React Compiler-on. .babelrc.js enables the React Compiler unless REACT_COMPILER=false, package.json adds build:no-compiler/bench:no-compiler scripts and drops react-window, and docs/guidelines are updated to reflect the new scenario names/variance expectations and compiler opt-out flow.

Written by Cursor Bugbot for commit f31caa5. This will update automatically on new commits. Configure here.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 21, 2026

⚠️ No Changeset found

Latest commit: f31caa5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs-site Ignored Ignored Preview Mar 21, 2026 4:30pm

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 21, 2026

Size Change: 0 B

Total Size: 80.5 kB

ℹ️ View Unchanged
Filename Size
examples/test-bundlesize/dist/App.js 3.18 kB
examples/test-bundlesize/dist/polyfill.js 307 B
examples/test-bundlesize/dist/rdcClient.js 10.2 kB
examples/test-bundlesize/dist/rdcEndpoint.js 6.35 kB
examples/test-bundlesize/dist/react.js 59.7 kB
examples/test-bundlesize/dist/webpack-runtime.js 726 B

compressed-size-action

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Benchmark React

Details
Benchmark suite Current: f31caa5 Previous: e4371de Ratio
data-client: getlist-100 17.3 ms (± 1.21) 21.4 ms (± 2.29) 0.81
data-client: getlist-500 39.9 ms (± 1.18) 33.1 ms (± 3.14) 1.21
data-client: update-entity 3.8 ms (± 0.35)
data-client: ref-stability-issue-changed 50 count (± 0) 5 count (± 0) 10
data-client: ref-stability-user-changed 50 count (± 0) 5 count (± 0) 10
data-client: update-user 4.8 ms (± 0.10)
data-client: getlist-500-sorted 38.5 ms (± 2.65)
data-client: update-entity-sorted 4.7 ms (± 0.39)
data-client: list-detail-switch 151 ms (± 28.23) 84.6 ms (± 1.08) 1.78
data-client: update-user-10000 21.9 ms (± 2.55)
data-client: invalidate-and-resolve 29.4 ms (± 1.94) 12 ms (± 1.52) 2.45
data-client: unshift-item 5.2 ms (± 0.35) 7.4 ms (± 0.52) 0.70
data-client: delete-item 4.4 ms (± 0.39) 7.1 ms (± 0.24) 0.62
data-client: move-item 5.8 ms (± 0.13) 5 ms (± 0.62) 1.16

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Drop react-window in favor of plain keyed lists with a configurable
renderLimit that caps DOM rendering while keeping all data in the store.
This decouples store size from DOM pressure and lets React reconcile
by key instead of index.

Also:
- Rename scenarios for clarity (update-entity, update-user, etc.)
- Increase default mountCount to 1000 for update/ref-stability scenarios
- Make React Compiler the default build (opt-out with REACT_COMPILER=false)

Made-with: Cursor
@ntucker ntucker force-pushed the bench-react-render-limit branch from 5178002 to f31caa5 Compare March 21, 2026 16:30
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.06%. Comparing base (bb13a80) to head (f31caa5).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3803   +/-   ##
=======================================
  Coverage   98.06%   98.06%           
=======================================
  Files         151      151           
  Lines        2843     2843           
  Branches      556      556           
=======================================
  Hits         2788     2788           
  Misses         11       11           
  Partials       44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ntucker ntucker merged commit 42114c8 into master Mar 21, 2026
24 checks passed
@ntucker ntucker deleted the bench-react-render-limit branch March 21, 2026 16:39
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