perf(loader): schedule loader chains as execution units - #15401
perf(loader): schedule loader chains as execution units#15401intellild wants to merge 4 commits into
Conversation
📦 Binary Size-limit
🎉 Size decreased by 76.00KB from 68.48MB to 68.40MB (⬇️0.11%) |
Rsdoctor Bundle Diff AnalysisFound 5 projects in monorepo, 0 projects with changes. 📊 Quick Summary
Generated by Rsdoctor GitHub Action |
Merging this PR will not alter performance
Comparing Footnotes
|
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 788f2e2bb4
ℹ️ 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".
9cbb92f to
7364cb1
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
7364cb1 to
42ce415
Compare
|
@codspeedbot is this regression real? |
Short answer: mostly no. 12 of the 13 flagged benchmarks cannot execute any code this PR touches — the steps there are a whole-binary codegen shift. The one number that reflects real work is The flagged 13 are not measuring your change
Call counts are identical; the delta lives entirely inside the hash-map lookup internals, which the two binaries inline differently (main goes through The one real cost:
|
b0303f1 to
349fc09
Compare
b4ecb7f to
7e9b4ce
Compare
Summary
Extract the LoaderChain execution-unit optimization from #15225 onto current
main, while keeping the currentCacheFacade/ItemCacheFacadestorage implementation unchanged.The loader cache is resolved for the complete cacheable LoaderChain on the Rust side immediately before normal-chain execution decides whether it needs to yield to JavaScript:
For example, for a cacheable
babel-loader -> custom JS loaderchain, a warm cache hit restores the normal-chain result in Rust and does not schedule the Babel transform on the JavaScript worker. In a fresh process, pitching may still enter JavaScript once to discover that a loader has no pitch function. On a miss, adjacent JavaScript loaders run as one execution unit and the final chain result is stored once.To minimize the surface relative to
main, this PR:LoaderCacheActionmodel instead of introducing a separate chain action;main's JS loader version identity by keepingloader_cache_versionin the Rust resolver, while removing only the old JS cache binding;loader_cache_key, without addingloader_chain_cache_keyor serializing a synthetic loader name inbefore_normal_chain;LoaderDependencies::difference/is_subset_of;ArcComputedowners to bePin<Arc<T>>, withLoadersandResolvedModuleOptionscreated throughArc::pinbefore computed references can be formed.Performance
Release-to-release Babel-only warm benchmark in
/Users/bytedance/projects/mock-oai:fee86872f3, locally built withbuild:release;@rspack/core@2.2.1with its release binding;experiments.newCacheenabled;builtin:swc-loadercaching disabled in every run;With loader cache enabled, the branch is 1.39x faster than published Rspack 2.2.1 with Babel parallel off and 1.79x faster with parallel on. Within the branch, enabling loader cache reduces the median by 82.50% (5.71x) with parallel off and 58.30% (2.40x) with parallel on.
Within the branch's warm-cache results, parallel on is 0.72 s (6.45%) slower than parallel off: 11.88 s versus 11.16 s. The normal Babel transform is skipped on a Rust cache hit, but the cache lookup currently happens after pitching. A fresh benchmark process can therefore still cross Rust → main-thread JavaScript to load the loader and discover that it has no pitch function, while parallel mode also carries its loader metadata and scheduling bookkeeping. Across 10,895 code modules, the 0.72 s delta is about 66 µs per module, which is consistent with coordination overhead rather than Babel transformation work.
The parallel-on/cache-off result is 4.74% slower than the published baseline; the other cache-off result is 4.88% faster. SWC loader caching was intentionally excluded so the comparison focuses on Babel loader execution and cache behavior.
Related links
Validation
cargo check -p rspack_util -p rspack_cacheable -p rspack_loader_runner -p rspack_core -p rspack_plugin_javascript -p rspack_plugin_css --all-targets --lockedcargo check -p rspack_binding_api --all-targets --lockedcargo test -p rspack_loader_runner --locked(10 passed)cargo test -p rspack_core lazily_reuse_parser_and_generator_options_for_rule_ids --locked(1 passed)pnpm --filter @rspack/binding run build:releasegit diff --checkChecklist
by OpenAI Codex