Skip to content

perf: benchmark incremental HMR rebuilds - #14955

Open
LingyuCoder wants to merge 1 commit into
mainfrom
seal/perf-incremental-hmr-codspeed
Open

perf: benchmark incremental HMR rebuilds#14955
LingyuCoder wants to merge 1 commit into
mainfrom
seal/perf-incremental-hmr-codspeed

Conversation

@LingyuCoder

Copy link
Copy Markdown
Contributor

Summary

Add CodSpeed coverage for the incremental optimization stack. The benchmark uses a large code-split graph with CSS and copied assets, performs repeated JavaScript and CSS leaf rebuilds, and exercises the native watcher lifecycle and event path.

The cases provide a common baseline for evaluating the graph reuse, process-assets, copy cache, HMR runtime, CSS HMR, and watcher changes in the dependent pull requests.

Related links

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

📝 Benchmark detail: Open

No benchmark data for commit fe6890c, trying parent...

Name Base (e39db0c) Current Change
10000_big_production-mode_disable-minimize + exec - 12.1 s ± 268 ms -
10000_development-mode + exec - 899 ms ± 62 ms -
10000_development-mode_hmr + stats - 164 ms ± 9 ms -
10000_development-mode_noop-loader + exec - 1.79 s ± 97 ms -
10000_production-mode + exec - 1.06 s ± 85 ms -
10000_production-mode_persistent-cold + exec - 1.21 s ± 36 ms -
10000_production-mode_persistent-hot + exec - 644 ms ± 9.5 ms -
10000_production-mode_source-map + exec - 1.2 s ± 39 ms -
arco-pro_development-mode + exec - 1.31 s ± 100 ms -
arco-pro_development-mode_hmr + stats - 34 ms ± 0.78 ms -
arco-pro_production-mode + exec - 2.36 s ± 118 ms -
arco-pro_production-mode_generate-package-json-webpack-plugin + exec - 2.43 s ± 171 ms -
arco-pro_production-mode_persistent-cold + exec - 2.44 s ± 165 ms -
arco-pro_production-mode_persistent-hot + exec - 346 ms ± 5.5 ms -
arco-pro_production-mode_source-map + exec - 2.84 s ± 170 ms -
arco-pro_production-mode_source-map_persistent-cold + exec - 2.97 s ± 67 ms -
arco-pro_production-mode_source-map_persistent-hot + exec - 477 ms ± 8.5 ms -
arco-pro_production-mode_traverse-chunk-modules + exec - 2.36 s ± 103 ms -
bundled-threejs_development-mode + exec - 187 ms ± 16 ms -
bundled-threejs_production-mode + exec - 212 ms ± 10 ms -
large-dyn-imports_development-mode + exec - 1.18 s ± 22 ms -
large-dyn-imports_production-mode + exec - 1.26 s ± 12 ms -
threejs_development-mode_10x + exec - 778 ms ± 28 ms -
threejs_development-mode_10x_hmr + stats - 111 ms ± 4.9 ms -
threejs_production-mode_10x + exec - 2.84 s ± 14 ms -
threejs_production-mode_10x_persistent-cold + exec - 2.97 s ± 35 ms -
threejs_production-mode_10x_persistent-hot + exec - 386 ms ± 6.7 ms -
threejs_production-mode_10x_source-map + exec - 3.66 s ± 72 ms -
10000_big_production-mode_disable-minimize + rss memory - 2195 MiB ± 25.4 MiB -
10000_development-mode + rss memory - 541 MiB ± 6.66 MiB -
10000_development-mode_hmr + rss memory - 766 MiB ± 53.7 MiB -
10000_development-mode_noop-loader + rss memory - 807 MiB ± 6.85 MiB -
10000_production-mode + rss memory - 465 MiB ± 8.9 MiB -
10000_production-mode_persistent-cold + rss memory - 662 MiB ± 5.01 MiB -
10000_production-mode_persistent-hot + rss memory - 654 MiB ± 33.7 MiB -
10000_production-mode_source-map + rss memory - 487 MiB ± 35 MiB -
arco-pro_development-mode + rss memory - 399 MiB ± 2.69 MiB -
arco-pro_development-mode_hmr + rss memory - 420 MiB ± 7.94 MiB -
arco-pro_production-mode + rss memory - 577 MiB ± 4.72 MiB -
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory - 592 MiB ± 10.2 MiB -
arco-pro_production-mode_persistent-cold + rss memory - 662 MiB ± 29.8 MiB -
arco-pro_production-mode_persistent-hot + rss memory - 292 MiB ± 4.81 MiB -
arco-pro_production-mode_source-map + rss memory - 672 MiB ± 15.9 MiB -
arco-pro_production-mode_source-map_persistent-cold + rss memory - 815 MiB ± 20.3 MiB -
arco-pro_production-mode_source-map_persistent-hot + rss memory - 416 MiB ± 8.96 MiB -
arco-pro_production-mode_traverse-chunk-modules + rss memory - 578 MiB ± 9.47 MiB -
bundled-threejs_development-mode + rss memory - 126 MiB ± 2.45 MiB -
bundled-threejs_production-mode + rss memory - 136 MiB ± 6.8 MiB -
large-dyn-imports_development-mode + rss memory - 554 MiB ± 14.6 MiB -
large-dyn-imports_production-mode + rss memory - 406 MiB ± 7.65 MiB -
threejs_development-mode_10x + rss memory - 435 MiB ± 16.2 MiB -
threejs_development-mode_10x_hmr + rss memory - 594 MiB ± 15.4 MiB -
threejs_production-mode_10x + rss memory - 623 MiB ± 13 MiB -
threejs_production-mode_10x_persistent-cold + rss memory - 572 MiB ± 25.6 MiB -
threejs_production-mode_10x_persistent-hot + rss memory - 371 MiB ± 9.02 MiB -
threejs_production-mode_10x_source-map + rss memory - 741 MiB ± 19.2 MiB -

Current persistent cache hit rate: 👍

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying rspack with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6df3520
Status: ✅  Deploy successful!
Preview URL: https://b7a5e6e1.rspack-v2.pages.dev
Branch Preview URL: https://seal-perf-incremental-hmr-co.rspack-v2.pages.dev

View logs

@github-actions

Copy link
Copy Markdown
Contributor

📦 Binary Size-limit

Comparing 6df3520 to chore(deps): update dependency markdown-to-jsx to ^9.9.0 (#14940) by renovate[bot]

🙈 Size remains the same at 66.79MB

@github-actions

Copy link
Copy Markdown
Contributor

Rsdoctor Bundle Diff Analysis

Found 5 projects in monorepo, 5 projects with changes.

📊 Quick Summary
Project Total Size Gzip Size Change Gzip Change
popular-libs 1.7 MB 552.1 KB - -
react-10k 5.6 MB 1.3 MB - -
react-1k 823.1 KB 217.0 KB - -
react-5k 2.7 MB 663.8 KB - -
ui-components 4.9 MB 1.4 MB - -
📋 Detailed Reports (Click to expand)

📁 popular-libs

Path: ../build-tools-performance/cases/popular-libs/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 1.7 MB - -
🗜️ Gzip Size 552.1 KB - -
📄 JavaScript 1.7 MB - -
🎨 CSS 0 B - -
🌐 HTML 289.0 B - -
📁 Other Assets 0 B - -

📁 react-10k

Path: ../build-tools-performance/cases/react-10k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 5.6 MB - -
🗜️ Gzip Size 1.3 MB - -
📄 JavaScript 5.6 MB - -
🎨 CSS 21.0 B - -
🌐 HTML 328.0 B - -
📁 Other Assets 0 B - -

📁 react-1k

Path: ../build-tools-performance/cases/react-1k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 823.1 KB - -
🗜️ Gzip Size 217.0 KB - -
📄 JavaScript 822.7 KB - -
🎨 CSS 0 B - -
🌐 HTML 328.0 B - -
📁 Other Assets 0 B - -

📁 react-5k

Path: ../build-tools-performance/cases/react-5k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 2.7 MB - -
🗜️ Gzip Size 663.8 KB - -
📄 JavaScript 2.7 MB - -
🎨 CSS 21.0 B - -
🌐 HTML 328.0 B - -
📁 Other Assets 0 B - -

📁 ui-components

Path: ../build-tools-performance/cases/ui-components/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 4.9 MB - -
🗜️ Gzip Size 1.4 MB - -
📄 JavaScript 4.8 MB - -
🎨 CSS 112.1 KB - -
🌐 HTML 328.0 B - -
📁 Other Assets 0 B - -

Generated by Rsdoctor GitHub Action

@codspeed-hq

codspeed-hq Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 46 untouched benchmarks
🆕 3 new benchmarks
⏩ 47 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation rust@incremental_hmr@css_leaf_edit N/A 179.2 ms N/A
🆕 Simulation rust@incremental_hmr@native_watcher_cycle N/A 76.4 µs N/A
🆕 Simulation rust@incremental_hmr@stable_graph_leaf_edit N/A 178.6 ms N/A

Comparing seal/perf-incremental-hmr-codspeed (6df3520) with main (e39db0c)2

Open in CodSpeed

Footnotes

  1. 47 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (fe6890c) during the generation of this report, so e39db0c was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@LingyuCoder
LingyuCoder marked this pull request as ready for review July 28, 2026 02:38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6df3520679

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +140 to +142
for _ in 0..32 {
watcher.trigger_event(&ArcPath::from(watched_file.as_str()), FsEventKind::Change);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Advance the mtime before injecting watcher changes

For an existing watched file, watch() records its current mtime, and Trigger::on_event suppresses a Change when that mtime has not advanced. Because this loop never modifies the file after registration, all 32 synthetic events are filtered before reaching the executor, so this benchmark cannot measure event aggregation or handler dispatch as intended. Mutate the file before triggering, or inject benchmark events below the stale-event filter and await their delivery.

Useful? React with 👍 / 👎.

),
(std::iter::empty(), std::iter::empty()),
(std::iter::empty(), std::iter::empty()),
std::time::SystemTime::UNIX_EPOCH,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid scheduling a startup event from the epoch

For this freshly created watched file, passing UNIX_EPOCH makes the watcher's startup scanner unconditionally classify it as changed because its mtime is newer than the supplied start time. The scan runs asynchronously, so that extra event races with pause() and close(), causing samples to inconsistently include or abort handler work unrelated to the explicit event loop. Use a start time at or after fixture setup and synchronize completion of the events being measured.

Useful? React with 👍 / 👎.

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