Skip to content

[code-infra] Port the benchmarks to new library - #5974

Merged
Janpot merged 33 commits into
mui:masterfrom
Janpot:janpot/benchmark-cli
Oct 23, 2026
Merged

Janpot merged 33 commits into
mui:masterfrom
Janpot:janpot/benchmark-cli

Conversation

@Janpot

@Janpot Janpot commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Closes #5403

Ports the benchmarks to the benchmark CLI from mui/mui-public#1898 (@mui/internal-benchmark 0.1.1-canary.8), the way mui/base-ui-charts#1186 and mui/material-ui#49329 do, and removes the Vitest benchmarks in test/performance.

smoke/smoke.bench.tsx mounts each of the library's 36 components in a benchmark of its own; the runner shares one page load per round between a file's benchmarks, so the file costs little more than one. It replaces the separate mount benchmarks. The pull request job runs only the smoke file; the Combobox, Menu and Select open and typing cases stay, for a nightly run against the last release, to be set up separately, and so do the exit animation cases from #5987, which were already left out of CI.

Comparison

We ran both setups 10 times in CI on all 15 benchmarks. A good setup should therefore report "no change" every time. Any regression it reports is a false alarm.

Both time the same thing: React's render and the paint after it. Vitest runs on a 2-CPU machine, the new tool on a larger one.

Vitest (removed) New tool, separate files (earlier version of this PR)
Runs with a false alarm 4 of 10 0 of 10
Benchmarks flagged, in total 18 0
Precision ±12% to ±46% ±2% to ±8%
Precision, typical benchmark ±32% ±4.7%
Error margin each run reports, compared with reality about 7× too small about 1.1× too small
CI job time, typical (fastest–slowest) 4.9 (4.3–5.8) min 11.6 (9.7–14.2) min

Precision is roughly the smallest slowdown a setup can reliably catch.

The same check on the smoke file as the pull request job runs it now (10% threshold, 3 minutes per run):

Smoke file (36)
Runs with a false alarm 1 of 10 (Collapsible, render)
Precision, typical ±9% render, ±8% paint
Error margin vs reality about 1.0× (accurate)
CI job time 5.4 (4.0–6.0) min

The smoke file gets 30 to 70 rounds within its time limit, so it is less precise than the separate files were; it is meant to catch big regressions. The one false alarm was a whole run off by +10% to +32% for Collapsible, which renders in a few milliseconds.

The pull request comment can also list an improvement on unchanged code, such as Dialog paint and Scroll Area render here. A regression only alarms once it is confidently past the 10% threshold, but any confirmed change for the better was listed, so across 36 benchmarks chance alone listed one now and then. Since mui/mui-public#1974 (canary.8), improvements are held to the same threshold.

Library fixes

The Slider, composite item and Scroll Area fixes that came with this pull request move to their own pull requests once it's merged, so each one is benchmarked against master.

test/benchmark holds the same benchmarks as test/performance, on reactBenchmark() from @mui/internal-benchmark/page, run by the benchmark CLI from mui/mui-public#1898 (its preview build). test/performance stays for comparison as test:benchmark:vitest.
@Janpot Janpot mentioned this pull request Oct 12, 2026
3 tasks
@pkg-pr-new

pkg-pr-new Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

commit: 7538d51

@code-infra-dashboard

code-infra-dashboard Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

No regressions in 36 benchmarks · ran 4m 17s · details


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 7538d51
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6adb6fbebcd35d1648cef654
😎 Deploy Preview https://deploy-preview-5974--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

…as artifacts

The .lintignore entries were appended onto its last line. The artifacts are TEMPORARY, while the benchmark setups are compared on repeated runs.
@Janpot Janpot added the internal Behind-the-scenes enhancement. Formerly called “core”. label Oct 12, 2026
Janpot added 22 commits October 12, 2026 10:33
Shortens the Benchmark CLI check on pull requests; with 50 rounds and 3 minutes it took 19 minutes for the 15 benchmarks.
test/benchmark runs the same cases with the same metrics, so the Vitest suite in
test/performance and its CI job go. The CLI job takes over the 'Benchmark tests'
name.
…y component

smoke/smoke.bench.tsx mounts each of the library's 36 components on its own, at a
modest count; the runner shares a page load per round between a file's benchmarks
(mui/mui-public#1898 at 621b803), so they cost little more than one. The separate
mount benchmarks and the mixed surface it duplicates go; the Combobox, Menu and
Select open and typing cases stay.
The rows were built inside each render function, so every sample built them again
inside the timed window. Also picks up mui/mui-public#1898 at feb4328, which stops
the page build from warning about every 'use client' directive.
A round of the whole smoke file takes about 4 s in CI, so a minute fit about 15
rounds past the sample size, too few to settle at the 5% band.
smokeBenchmark(name, count, renderRow) creates the rows once per page load and
applies the shared sampling, so each case is just the component it mounts. Picks up
mui/mui-public#1898 at f172e98.
…s the sample size; graceful stop on a signal
The open and typing benchmarks stay, for a fuller run against the last release to be
set up separately.
Their CI precision is about ±10%; at the default 5% band, a run of unchanged code
flagged one of them in 10. They are there to catch big regressions.
The 30-round sample size moves from the CI command into SMOKE_OPTIONS, so a local run
samples the same way; the 3-minute timeout was the default and goes. The comments say
why without numbers that drift.
@Janpot Janpot changed the title [test] Port the benchmarks to the benchmark CLI [code-infra] Port the benchmarks to new library Oct 14, 2026
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Oct 16, 2026
# Conflicts:
#	.circleci/config.yml
#	packages/react/src/slider/root/SliderRoot.tsx
#	packages/react/src/slider/value/SliderValue.tsx
#	pnpm-lock.yaml
#	test/performance/package.json
…ction

The harness typechecks Base UI through its typecheck project, as the package does.
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Oct 20, 2026
@Janpot
Janpot marked this pull request as ready for review October 20, 2026 12:36
@Janpot
Janpot requested a review from a team October 22, 2026 09:32
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Oct 23, 2026
# Conflicts:
#	test/benchmark/src/exit-animations.bench.tsx
#	test/performance/vitest.config.ts
@github-actions github-actions Bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Oct 23, 2026
@Janpot
Janpot merged commit c1294ab into mui:master Oct 23, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Behind-the-scenes enhancement. Formerly called “core”.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant