Skip to content

Comments

Add ideal graph native bundling algorithm#1025

Open
mattcompiles wants to merge 38 commits intomainfrom
matt/ideal-graph
Open

Add ideal graph native bundling algorithm#1025
mattcompiles wants to merge 38 commits intomainfrom
matt/ideal-graph

Conversation

@mattcompiles
Copy link
Contributor

Motivation

The existing bundling algorithm lives in JS and is one of the targets for native migration. This adds a Rust
implementation of the ideal graph bundling algorithm behind the nativeBundling feature flag. It's still a work in progress, but it's enough to build a real world app.

Changes

• Add the ideal graph bundler implementation (ideal_graph/builder.rs, ideal_graph/types.rs, ideal_graph/mod.rs) with
all core phases: boundary identification, sync graph construction, reachability, asset placement, availability,
shared bundle creation, and async bundle internalization
• Add conversion layer from IdealGraph back to NativeBundleGraph for integration with the existing pipeline
• Add a comprehensive benchmark suite with configurable graph generation that approximates real-world app
characteristics
• Add native bundler parity integration tests
• Fix an O(N^2) in from_asset_graph that was causing massive slowdowns in the bundle graph request
• Wire up the native bundler behind setupV3Flags({nativeBundling: true})

Checklist

  • Existing or new tests cover this change
  • There is a changeset for this change, or one is not required

…edup

Replace String-based IdealBundleId with u32-based keys backed by AssetInterner.
All HashMap/HashSet operations now use integer hashing instead of string hashing.

Real app results (60k assets):
- create_shared_bundles: 1.85s -> 403ms (4.6x)
- compute_availability: 1.57s -> 129ms (12x)
- internalize_async: 710ms -> 259ms (2.7x)
- Total build: 4.54s -> 1.18s (3.8x)

Combined with previous optimizations: 86.9s -> 1.18s (74x total)
Replace HashMap<IdealBundleId, IdealBundle> with Vec<Option<IdealBundle>>
indexed by the u32 bundle ID. Eliminates hash computation for all bundle
lookups and mutations.

Benchmark: 7.6% improvement at xlarge (60k assets, 2.79s -> 2.57s).
…y pass

Remove compute_availability_dag_fast and compute_availability_dag functions
(~290 lines). Real apps always have cycles, so the DAG fast path was wasted
work that always fell through to SCC condensation.

Reorder phases to match JS version: availability -> internalize -> shared
bundles. This eliminates the second availability recomputation after shared
bundle insertion.

Real app results (60k assets): 1.18s -> 861ms (-27%)
Overall journey: 86.9s -> 861ms (101x total speedup)
…onversion

Fix two critical performance bottlenecks outside the bundling algorithm:

1. from_asset_graph: move node_weights().collect() outside edge loop
   - Was creating 60k-element Vec for each of 223k edges
   - ~91s eliminated

2. Bundle conversion: precompute deps_by_target HashMap
   - Three O(N*M) loops iterated all 223k deps for each of ~7k bundles
   - ~34s eliminated

Real app results (60k assets):
- bundle_graph_request: 127s -> 1.77s (72x)
- build_bundle_graph: 165s -> 43.6s (3.8x, limited by asset graph build)
@mattcompiles mattcompiles requested a review from a team as a code owner February 16, 2026 05:25
@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2026

🦋 Changeset detected

Latest commit: 912dc4c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 112 packages
Name Type
@atlaspack/rust Patch
@atlaspack/core Patch
@atlaspack/bundler-default Patch
atlaspack Patch
@atlaspack/cache Patch
@atlaspack/e2e-tests Patch
@atlaspack/fs Patch
@atlaspack/logger Patch
@atlaspack/source-map Patch
@atlaspack/utils Patch
@atlaspack/link Patch
@atlaspack/packaging-test-harness Patch
@atlaspack/optimizer-image Patch
@atlaspack/optimizer-inline-requires Patch
@atlaspack/packager-js Patch
@atlaspack/transformer-compiled-css-in-js Patch
@atlaspack/transformer-html Patch
@atlaspack/transformer-js Patch
@atlaspack/transformer-postcss Patch
@atlaspack/transformer-svg Patch
@atlaspack/transformer-tokens Patch
@atlaspack/node-resolver-core Patch
@atlaspack/config-default Patch
@atlaspack/config-webextension Patch
@atlaspack/cli Patch
@atlaspack/register Patch
@atlaspack/test-utils Patch
@atlaspack/inspector Patch
@atlaspack/bundle-stats Patch
@atlaspack/query Patch
@atlaspack/reporter-bundle-stats Patch
@atlaspack/transformer-image Patch
@atlaspack/inspector-frontend Patch
@atlaspack/package-manager Patch
@atlaspack/profiler Patch
@atlaspack/workers Patch
@atlaspack/watcher-watchman-js Patch
@atlaspack/types-internal Patch
@atlaspack/optimizer-css Patch
@atlaspack/optimizer-cssnano Patch
@atlaspack/optimizer-swc Patch
@atlaspack/optimizer-terser Patch
@atlaspack/packager-css Patch
@atlaspack/transformer-babel Patch
@atlaspack/transformer-compiled-external Patch
@atlaspack/transformer-compiled Patch
@atlaspack/transformer-css Patch
@atlaspack/transformer-less Patch
@atlaspack/transformer-sass Patch
@atlaspack/transformer-typescript-tsc Patch
@atlaspack/transformer-typescript-types Patch
@atlaspack/optimizer-blob-url Patch
@atlaspack/optimizer-data-url Patch
@atlaspack/optimizer-svgo Patch
@atlaspack/packager-html Patch
@atlaspack/packager-raw-url Patch
@atlaspack/packager-svg Patch
@atlaspack/packager-webextension Patch
@atlaspack/packager-xml Patch
@atlaspack/reporter-build-metrics Patch
@atlaspack/reporter-bundle-analyzer Patch
@atlaspack/reporter-cli Patch
@atlaspack/reporter-dev-server Patch
@atlaspack/reporter-json Patch
@atlaspack/reporter-lsp Patch
@atlaspack/reporter-sourcemap-visualiser Patch
@atlaspack/reporter-tracer Patch
@atlaspack/resolver-glob Patch
@atlaspack/runtime-browser-hmr Patch
@atlaspack/runtime-js Patch
@atlaspack/runtime-react-refresh Patch
@atlaspack/runtime-service-worker Patch
@atlaspack/runtime-webextension Patch
@atlaspack/transformer-posthtml Patch
@atlaspack/transformer-react-refresh-wrap Patch
@atlaspack/transformer-webextension Patch
@atlaspack/transformer-webmanifest Patch
@atlaspack/validator-eslint Patch
@atlaspack/validator-typescript Patch
@atlaspack/resolver-default Patch
@atlaspack/resolver-tesseract Patch
@atlaspack/types Patch
@atlaspack/codeframe Patch
@atlaspack/graph Patch
@atlaspack/plugin Patch
@atlaspack/reporter-bundle-buddy Patch
@atlaspack/transformer-xml Patch
@atlaspack/ts-utils Patch
@atlaspack/packager-ts Patch
@atlaspack/transformer-jsonld Patch
@atlaspack/bundler-library Patch
@atlaspack/compressor-brotli Patch
@atlaspack/compressor-gzip Patch
@atlaspack/compressor-raw Patch
@atlaspack/namer-default Patch
@atlaspack/optimizer-htmlnano Patch
@atlaspack/packager-raw Patch
@atlaspack/packager-wasm Patch
@atlaspack/reporter-compiled-css-in-js-migration-map Patch
@atlaspack/reporter-conditional-manifest Patch
@atlaspack/transformer-glsl Patch
@atlaspack/transformer-graphql Patch
@atlaspack/transformer-inline-string Patch
@atlaspack/transformer-inline Patch
@atlaspack/transformer-json Patch
@atlaspack/transformer-mdx Patch
@atlaspack/transformer-pug Patch
@atlaspack/transformer-raw Patch
@atlaspack/transformer-svg-react Patch
@atlaspack/transformer-toml Patch
@atlaspack/transformer-worklet Patch
@atlaspack/transformer-yaml Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

📊 Type Coverage Report

Coverage Comparison

Metric Baseline Current Change
Coverage Percentage 92.23% 92.24% 📈 +0.01%
Correctly Typed 219,181 219,419 +238
Total Expressions 237,630 237,868 +238
Untyped Expressions 18,449 18,449 +0

Files with Most Type Issues (Top 15)

File Issues Affected Lines
packages/core/integration-tests/test/javascript.ts 1152 745
packages/core/integration-tests/test/cache.ts 885 626
packages/core/integration-tests/test/scope-hoisting.ts 622 489
packages/utils/node-resolver-core/test/resolver.ts 476 177
packages/core/integration-tests/test/html.ts 468 294
packages/core/integration-tests/test/sourcemaps.ts 356 176
packages/core/test-utils/src/utils.ts 330 205
packages/core/integration-tests/test/incremental-bundling.ts 298 206
packages/core/core/src/dumpGraphToGraphViz.ts 251 108
packages/core/integration-tests/test/transpilation.ts 230 139
packages/core/integration-tests/test/output-formats.ts 227 161
packages/transformers/webextension/src/WebExtensionTransformer.ts 210 80
packages/core/core/src/requests/BundleGraphRequestRust.ts 194 67
packages/core/integration-tests/test/css-modules.ts 191 107
packages/core/core/src/requests/TargetRequest.ts 190 133

This report was generated by the Type Coverage GitHub Action

Copy link
Contributor

@marcins marcins left a comment

Choose a reason for hiding this comment

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

There's way too much stuff here to really get a good mental context of it, but conceptually looks fine to me!

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.

2 participants