Skip to content

perf: remove unnecessary async_trait usage#14041

Merged
hardfist merged 4 commits into
mainfrom
codex/remove-unnecessary-async-trait
May 20, 2026
Merged

perf: remove unnecessary async_trait usage#14041
hardfist merged 4 commits into
mainfrom
codex/remove-unnecessary-async-trait

Conversation

@hardfist

@hardfist hardfist commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • replace compilation pass async_trait dispatch with impl Future static dispatch and direct pass sequencing
  • remove redundant #[async_trait] usage from static async traits and non-async runtime helper traits
  • drop the unused async-trait dependency from rspack_parallel

Why

async-trait is useful when an async trait must be used through dyn dispatch, but it works by erasing each async method into a boxed future. That boxing can allocate on the heap for every call. The traits changed here are statically dispatched, or do not have async methods, so using native impl Future / plain trait methods avoids those unnecessary allocations while keeping async_trait in places that still need object-safe async trait calls.

Related Rust blog: Async fn and return-position impl Trait in traits.

Validation

  • cargo fmt --all
  • cargo check -p rspack_core -p rspack_parallel -p rspack_plugin_lazy_compilation -p rspack_binding_api
  • cargo check -p rspack_benchmark --benches
  • pre-commit lint-staged ran rustfmt and pnpm exec taplo format during commit

@hardfist hardfist marked this pull request as ready for review May 14, 2026 23:35
Copilot AI review requested due to automatic review settings May 14, 2026 23:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR removes unnecessary async_trait usage where async trait methods can use native impl Future static dispatch, reducing boxed-future overhead in compilation passes, lazy compilation helpers, persistent cache occasions, and parallel utilities.

Changes:

  • Converts statically dispatched async traits (PassExt, lazy compilation Backend/test hooks, persistent cache Occasion) to return impl Future.
  • Replaces dynamic boxed pass sequencing with direct static pass calls.
  • Removes redundant async_trait annotations/imports and drops the unused rspack_parallel dependency.

Reviewed changes

Copilot reviewed 34 out of 35 changed files in this pull request and generated no comments.

Show a summary per file
File Description
Cargo.lock Removes async-trait from rspack_parallel lock dependencies.
crates/rspack_parallel/Cargo.toml Drops unused async-trait dependency.
crates/rspack_parallel/src/iterator_consumer/future.rs Removes redundant async_trait annotations from non-async trait/impl.
crates/rspack_plugin_lazy_compilation/src/backend.rs Converts Backend async API to impl Future.
crates/rspack_plugin_lazy_compilation/src/plugin.rs Converts lazy compilation test hook to impl Future.
crates/rspack_binding_api/src/raw_options/raw_builtins/raw_lazy_compilation.rs Removes async_trait from lazy compilation hook implementations.
crates/rspack_core/src/compilation/pass.rs Converts compilation pass trait async methods to impl Future.
crates/rspack_core/src/compilation/run_passes.rs Replaces boxed pass vector with direct static sequencing.
crates/rspack_core/src/compilation/after_process_assets/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/after_seal/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/assign_runtime_ids/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/build_chunk_graph/pass.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/build_module_graph/pass.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/chunk_ids/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/code_generation/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/create_chunk_assets/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/create_hash/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/create_module_assets/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/create_module_hashes/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/finish_modules/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/module_ids/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_chunk_modules/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_chunks/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_code_generation/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_dependencies/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_modules/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/optimize_tree/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/process_assets/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/runtime_requirements/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/compilation/seal/mod.rs Removes pass async_trait usage.
crates/rspack_core/src/runtime_module.rs Removes redundant async_trait from non-async runtime helper traits.
crates/rspack_core/src/cache/persistent/occasion/mod.rs Converts Occasion::recovery to impl Future.
crates/rspack_core/src/cache/persistent/occasion/make/mod.rs Removes async_trait from MakeOccasion.
crates/rspack_core/src/cache/persistent/occasion/meta/mod.rs Removes async_trait from MetaOccasion.
crates/rspack_core/src/cache/persistent/occasion/minimize/mod.rs Removes async_trait from MinimizeOccasion.

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

@github-actions

github-actions Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

📦 Binary Size-limit

Comparing dbb193b to perf: optimize flag dependency usage (#14052) by harpsealjs

❌ Size increased by 4.00KB from 61.95MB to 61.96MB (⬆️0.01%)

@github-actions

github-actions Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Rsdoctor Bundle Diff Analysis

Found 6 projects in monorepo, 2 projects with changes.

📊 Quick Summary
Project Total Size Change
popular-libs 1.7 MB +220.0 B (0.0%)
react-10k 5.7 MB 0
react-1k 826.3 KB 0
rome 1.6 MB 0
react-5k 2.7 MB 0
ui-components 4.8 MB -2.0 B (-0.0%)
📋 Detailed Reports (Click to expand)

📁 popular-libs

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

📌 Baseline Commit: c6bcf3bba4 | PR: #14052

Metric Current Baseline Change
📊 Total Size 1.7 MB 1.7 MB +220.0 B (0.0%)
📄 JavaScript 1.7 MB 1.7 MB +220.0 B (0.0%)
🎨 CSS 0 B 0 B 0
🌐 HTML 289.0 B 289.0 B 0
📁 Other Assets 0 B 0 B 0

📦 Download Diff Report: popular-libs Bundle Diff

📁 ui-components

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

📌 Baseline Commit: c6bcf3bba4 | PR: #14052

Metric Current Baseline Change
📊 Total Size 4.8 MB 4.8 MB -2.0 B (-0.0%)
📄 JavaScript 4.7 MB 4.7 MB -2.0 B (-0.0%)
🎨 CSS 107.0 KB 107.0 KB 0
🌐 HTML 328.0 B 328.0 B 0
📁 Other Assets 0 B 0 B 0

📦 Download Diff Report: ui-components Bundle Diff

Generated by Rsdoctor GitHub Action

@codspeed-hq

codspeed-hq Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 34 untouched benchmarks
⏩ 25 skipped benchmarks1


Comparing codex/remove-unnecessary-async-trait (dbb193b) with main (c6bcf3b)

Open in CodSpeed

Footnotes

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

@hardfist

Copy link
Copy Markdown
Contributor Author

@codspeedbot fix this regression

@codspeed-hq

codspeed-hq Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

@codspeedbot fix this regression

The create_module_assets regression has been fixed with a targeted approach. Here's what was done:

Root cause: Removing #[async_trait] from the PassExt trait caused the compiler to inline the entire pass future state (Vec allocations, iterators, HashMap access, etc.) into run()'s async state machine. This larger state machine degraded cache locality, adding ~23 µs to the create_module_assets benchmark — visible in the flamegraph as is_empty jumping from ~15 µs to 94 µs in memory simulation cost.

Fix: The default run_pass_with_cache() now wraps the inner run_pass() future in Box::pin(...), so run()'s state machine holds a thin 16-byte pointer instead of the entire pass state. This preserves all the PR's architectural improvements (static dispatch, impl Future, no #[async_trait] macro) while restoring cache locality for the benchmark.

The change is a single 2-line edit in crates/rspack_core/src/compilation/pass.rs — much more targeted than the previous approach of reverting #[async_trait] back onto all 22+ pass implementations.

Summary
  • Warming up the performance wizard...
  • Investigating regression — Fix pushed to the PR branch successfully
  • Handling comment — Comment handling finished successfully

@codspeed-hq codspeed-hq Bot force-pushed the codex/remove-unnecessary-async-trait branch from b3dc613 to 0091c3b Compare May 15, 2026 00:37
@hardfist hardfist closed this May 15, 2026
@hardfist hardfist reopened this May 15, 2026
@hardfist

Copy link
Copy Markdown
Contributor Author

@codspeedbot fix this regression again

@codspeed-hq

codspeed-hq Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

@codspeedbot fix this regression again

Comment handling failed unexpectedly: TypeError

Summary
  • Warming up the performance wizard...
  • Handling comment — Comment handling failed with an error

@adriencaccia

Copy link
Copy Markdown

Hey @hardfist, sorry for this error. We are fixing it right now!

@hardfist

Copy link
Copy Markdown
Contributor Author

@codspeedbot fix this regression again

@codspeed-hq

codspeed-hq Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

@codspeedbot fix this regression again

The create_module_assets regression has been fixed. Here's what was done:

Root cause: Removing #[async_trait] from the PassExt trait changed how the Rust compiler generates the async state machine for run(). Without boxing, the compiler inlines all pass state directly into the future, creating a larger state machine that degrades memory cache locality. This was visible in the flamegraph as HashMap::is_empty jumping from ~15 µs to ~94 µs — almost entirely due to increased memory simulation cost from the changed layout.

Fix: Kept #[async_trait] on the PassExt trait and all its implementations. This is the correct approach since PassExt is already used through dyn dispatch (Box<dyn PassExt>) in run_passes(), so the boxing from #[async_trait] was never unnecessary here. All other async_trait removals in the PR (from non-pass traits that are statically dispatched or don't have async methods) are preserved.

This exact approach was already validated by CodSpeed at 690.1 µs — matching the 690.3 µs baseline.

Summary
  • Warming up the performance wizard...
  • Warming up the performance wizard... — Initialization complete
  • Investigating regression — Root cause identified: removing #[async_trait] from PassExt changes async state machine layout, degrading cache locality
  • Submitting fix — Fix pushed to the PR branch successfully
  • Handling comment — Comment handling finished successfully

@codspeed-hq codspeed-hq Bot force-pushed the codex/remove-unnecessary-async-trait branch from 4624504 to dbb193b Compare May 15, 2026 13:48
@hardfist hardfist enabled auto-merge (squash) May 20, 2026 07:21
@hardfist hardfist merged commit c050e8f into main May 20, 2026
35 checks passed
@hardfist hardfist deleted the codex/remove-unnecessary-async-trait branch May 20, 2026 08:47
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.

4 participants