Skip to content

refactor(core): reduce concatenated module analysis overhead#13342

Draft
LingyuCoder wants to merge 1 commit intomainfrom
codex/perf-concatenated-10000
Draft

refactor(core): reduce concatenated module analysis overhead#13342
LingyuCoder wants to merge 1 commit intomainfrom
codex/perf-concatenated-10000

Conversation

@LingyuCoder
Copy link
Contributor

Summary

Reduce ConcatenatedModule overhead on the rspack-ecosystem-benchmark/cases/10000 case by:

  • removing the nested per-module async task fan-out inside concatenated-module analysis
  • storing global_scope_ident as plain Ident
  • only materializing full idents for modern-module library builds, where rspack_plugin_esm_library actually needs them

Benchmark

Case: /Users/bytedance/rspack-dev/rspack-ecosystem-benchmark/cases/10000

Local cold-run comparison with the same command shape (NODE_DISABLE_COMPILE_CACHE=1, rm -rf dist, direct RSPACK_BINDING):

  • base main: compile avg 5.45s, real avg 5.59s
  • this branch: compile avg 1.18s, real avg 1.65s

Verification

  • cargo fmt --all
  • cargo check -p rspack_core -p rspack_plugin_esm_library
  • local benchmark run on cases/10000

Notes

  • cargo lint was intentionally skipped at user request to speed up landing.

Copilot AI review requested due to automatic review settings March 13, 2026 09:41
@github-actions github-actions bot added the team The issue/pr is created by the member of Rspack. label Mar 13, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 2026

📝 Benchmark detail: Open

No benchmark data for commit 3e83955, trying parent...

Name Base (main cf2c8bc) Current Change
10000_big_production-mode_disable-minimize + exec 14.3 s ± 368 ms 14.4 s ± 214 ms +0.57 %
10000_development-mode + exec 962 ms ± 17 ms 952 ms ± 32 ms -1.10 %
10000_development-mode_hmr + stats 176 ms ± 5.7 ms 177 ms ± 6.9 ms +0.12 %
10000_development-mode_noop-loader + exec 2.08 s ± 39 ms 2.1 s ± 51 ms +0.92 %
10000_production-mode + exec 1.12 s ± 17 ms 1.19 s ± 34 ms +6.43 %
10000_production-mode_persistent-cold + exec 1.29 s ± 32 ms 1.38 s ± 52 ms +7.04 %
10000_production-mode_persistent-hot + exec 988 ms ± 27 ms 1.07 s ± 32 ms +8.48 %
10000_production-mode_source-map + exec 1.28 s ± 27 ms 1.37 s ± 31 ms +6.39 %
arco-pro_development-mode + exec 1.34 s ± 78 ms 1.34 s ± 76 ms 0.00 %
arco-pro_development-mode_hmr + stats 37 ms ± 0.66 ms 38 ms ± 1.8 ms +1.76 %
arco-pro_production-mode + exec 2.47 s ± 75 ms 2.48 s ± 71 ms +0.30 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 2.52 s ± 99 ms 2.53 s ± 90 ms +0.21 %
arco-pro_production-mode_persistent-cold + exec 2.53 s ± 41 ms 2.55 s ± 76 ms +0.97 %
arco-pro_production-mode_persistent-hot + exec 1.4 s ± 63 ms 1.4 s ± 51 ms -0.17 %
arco-pro_production-mode_source-map + exec 2.91 s ± 76 ms 2.93 s ± 79 ms +0.73 %
arco-pro_production-mode_traverse-chunk-modules + exec 2.49 s ± 90 ms 2.5 s ± 66 ms +0.45 %
bundled-threejs_development-mode + exec 195 ms ± 3.5 ms 195 ms ± 2.5 ms -0.21 %
bundled-threejs_production-mode + exec 229 ms ± 5.6 ms 238 ms ± 2.9 ms +3.66 %
large-dyn-imports_development-mode + exec 1.2 s ± 13 ms 1.2 s ± 18 ms +0.15 %
large-dyn-imports_production-mode + exec 1.32 s ± 34 ms 1.33 s ± 60 ms +0.52 %
threejs_development-mode_10x + exec 856 ms ± 37 ms 866 ms ± 34 ms +1.14 %
threejs_development-mode_10x_hmr + stats 119 ms ± 2.8 ms 119 ms ± 4.9 ms +0.18 %
threejs_production-mode_10x + exec 3.09 s ± 45 ms 3.31 s ± 111 ms +6.81 %
threejs_production-mode_10x_persistent-cold + exec 3.22 s ± 35 ms 3.41 s ± 51 ms +6.19 %
threejs_production-mode_10x_persistent-hot + exec 2.62 s ± 26 ms 2.84 s ± 82 ms +8.41 %
threejs_production-mode_10x_source-map + exec 3.82 s ± 86 ms 4 s ± 72 ms +4.83 %
10000_big_production-mode_disable-minimize + rss memory 2017 MiB ± 77.8 MiB 2029 MiB ± 72.7 MiB +0.62 %
10000_development-mode + rss memory 595 MiB ± 9.82 MiB 598 MiB ± 7.63 MiB +0.52 %
10000_development-mode_hmr + rss memory 810 MiB ± 39.4 MiB 812 MiB ± 28.9 MiB +0.16 %
10000_development-mode_noop-loader + rss memory 893 MiB ± 10.7 MiB 892 MiB ± 11.8 MiB -0.15 %
10000_production-mode + rss memory 546 MiB ± 21.4 MiB 520 MiB ± 8.73 MiB -4.68 %
10000_production-mode_persistent-cold + rss memory 737 MiB ± 19.1 MiB 748 MiB ± 12.8 MiB +1.53 %
10000_production-mode_persistent-hot + rss memory 745 MiB ± 16.2 MiB 749 MiB ± 11.3 MiB +0.57 %
10000_production-mode_source-map + rss memory 564 MiB ± 5.86 MiB 574 MiB ± 13.2 MiB +1.82 %
arco-pro_development-mode + rss memory 475 MiB ± 7.54 MiB 474 MiB ± 7 MiB -0.17 %
arco-pro_development-mode_hmr + rss memory 492 MiB ± 15.8 MiB 495 MiB ± 13.2 MiB +0.50 %
arco-pro_production-mode + rss memory 661 MiB ± 59.5 MiB 666 MiB ± 21.8 MiB +0.80 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 689 MiB ± 14.1 MiB 673 MiB ± 59.3 MiB -2.31 %
arco-pro_production-mode_persistent-cold + rss memory 749 MiB ± 8.7 MiB 742 MiB ± 17.7 MiB -0.86 %
arco-pro_production-mode_persistent-hot + rss memory 568 MiB ± 32.6 MiB 551 MiB ± 18.2 MiB -3.01 %
arco-pro_production-mode_source-map + rss memory 764 MiB ± 15 MiB 756 MiB ± 12.6 MiB -1.10 %
arco-pro_production-mode_traverse-chunk-modules + rss memory 673 MiB ± 17.4 MiB 667 MiB ± 17 MiB -0.87 %
bundled-threejs_development-mode + rss memory 161 MiB ± 5.66 MiB 154 MiB ± 2.1 MiB -4.92 %
bundled-threejs_production-mode + rss memory 180 MiB ± 9.77 MiB 174 MiB ± 8.11 MiB -3.30 %
large-dyn-imports_development-mode + rss memory 602 MiB ± 30.3 MiB 592 MiB ± 32.3 MiB -1.77 %
large-dyn-imports_production-mode + rss memory 455 MiB ± 5.4 MiB 450 MiB ± 7.57 MiB -0.98 %
threejs_development-mode_10x + rss memory 538 MiB ± 24.4 MiB 536 MiB ± 12 MiB -0.36 %
threejs_development-mode_10x_hmr + rss memory 670 MiB ± 10.7 MiB 676 MiB ± 26.2 MiB +0.91 %
threejs_production-mode_10x + rss memory 720 MiB ± 14 MiB 700 MiB ± 29.8 MiB -2.82 %
threejs_production-mode_10x_persistent-cold + rss memory 854 MiB ± 16.9 MiB 833 MiB ± 11.6 MiB -2.45 %
threejs_production-mode_10x_persistent-hot + rss memory 701 MiB ± 10.5 MiB 673 MiB ± 27.8 MiB -4.02 %
threejs_production-mode_10x_source-map + rss memory 851 MiB ± 14.4 MiB 848 MiB ± 15.6 MiB -0.38 %

Threshold exceeded: ["10000_production-mode + exec","10000_production-mode_persistent-cold + exec","10000_production-mode_persistent-hot + exec","10000_production-mode_source-map + exec","threejs_production-mode_10x + exec","threejs_production-mode_10x_persistent-cold + exec","threejs_production-mode_10x_persistent-hot + exec"]

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors concatenated-module analysis to reduce overhead and memory usage, with a focus on improving performance in large-module benchmarks.

Changes:

  • Removes nested per-module async task fan-out during concatenated-module analysis.
  • Stores global_scope_ident as swc_ecma_ast::Ident instead of a legacy wrapper type.
  • Avoids collecting/storing full idents except when modern-module library builds require them.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
crates/rspack_plugin_esm_library/src/link.rs Updates ESM library linking logic to match the new global_scope_ident shape (Ident), minimizing cloning overhead.
crates/rspack_core/src/concatenated_module.rs Refactors concatenation analysis flow, changes identifier storage to reduce work, and gates full ident materialization behind modern-module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +994 to 1010
let mut tmp = Vec::with_capacity(arc_map.len());
for (id, info) in arc_map.iter() {
let concatenation_scope = if let ModuleInfo::Concatenated(info) = info {
Some(ConcatenationScope::new(
self.id,
arc_map.clone(),
info.as_ref().clone(),
))
} else {
None
};

let mut updated_pairs = vec![];
for item in tmp {
updated_pairs.push(item?);
let updated_module_info = self
.analyze_module(compilation, info.clone(), runtime, concatenation_scope)
.await?;
tmp.push((*id, updated_module_info));
}
Comment on lines +1022 to +1045
async {
for (module_info_id, _) in references_info.iter() {
let Some(ModuleInfo::Concatenated(info)) = module_to_info_map.get_mut(module_info_id)
else {
continue;
};
if info.has_ast {
all_used_names.extend(info.all_used_names.clone());
}
}
}

for (id, info) in module_to_info_map.iter_mut() {
if let ModuleInfo::Concatenated(info) = info {
compilation
.plugin_driver
.concatenated_module_hooks
.concatenated_info
.call(compilation, *id, runtime, info, &mut all_used_names)
.await?;
for (id, info) in module_to_info_map.iter_mut() {
if let ModuleInfo::Concatenated(info) = info {
compilation
.plugin_driver
.concatenated_module_hooks
.concatenated_info
.call(compilation, *id, runtime, info, &mut all_used_names)
.await?;
}
}
Ok::<(), Error>(())
}
.await?;
Comment on lines +66 to +72
fn concat_needs_all_idents(compilation: &Compilation) -> bool {
compilation
.options
.output
.enabled_library_types
.as_ref()
.is_some_and(|types| types.iter().any(|ty| ty == "modern-module"))
@github-actions
Copy link
Contributor

Rsdoctor Bundle Diff Analysis

Found 5 projects in monorepo, 0 projects with changes.

📊 Quick Summary
Project Total Size Change
react-10k 5.7 MB 0
react-1k 826.2 KB 0
react-5k 2.7 MB 0
rome 984.2 KB 0
ui-components 2.3 MB 0

Generated by Rsdoctor GitHub Action

@github-actions
Copy link
Contributor

📦 Binary Size-limit

Comparing 572f6de to refactor: remove Ukey DataBase abstraction (#13339) by hardfist

🎉 Size decreased by 10.50KB from 49.04MB to 49.03MB (⬇️0.02%)

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 13, 2026

Merging this PR will not alter performance

✅ 16 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing codex/perf-concatenated-10000 (572f6de) with main (cf2c8bc)

Open in CodSpeed

Footnotes

  1. 3 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.

@LingyuCoder LingyuCoder marked this pull request as draft March 13, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: refactor team The issue/pr is created by the member of Rspack.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants