perf(module-federation): optimize path mappings and remote resolution
Current Behavior
1. typescript.ts - readTsPathMappings was O(n²)
The function was spreading the accumulator object on every iteration:
┌─────────────────────────────────────────────────────────────┐
│ BEFORE: O(n²) │
├─────────────────────────────────────────────────────────────┤
│ │
│ For each path alias (n=100): │
│ tsPathMappings.set(tsConfigPath, { │
│ ...tsPathMappings.get(tsConfigPath), ← SPREAD n items │
│ [alias]: paths │
│ }); │
│ │
│ Iteration 1: spread 0 items │
│ Iteration 2: spread 1 item │
│ Iteration 3: spread 2 items │
│ ... │
│ Iteration n: spread n-1 items │
│ │
│ Total: 0+1+2+...+(n-1) = n(n-1)/2 = O(n²) operations │
│ │
│ For 100 aliases: 4,950 spread operations │
│ │
└─────────────────────────────────────────────────────────────┘
2. get-remotes-for-host.ts - Multiple inefficiencies
Object.keys()called twice on same objectreplace()called twice on same string- Multiple array spreads for port calculation
Expected Behavior
1. typescript.ts - Now O(n)
┌─────────────────────────────────────────────────────────────┐
│ AFTER: O(n) │
├─────────────────────────────────────────────────────────────┤
│ │
│ const processedPaths = {}; │
│ for (const [alias, paths] of entries) { │
│ processedPaths[alias] = paths.map(normalize); │
│ } │
│ tsPathMappings.set(tsConfigPath, processedPaths); │
│ │
│ Total: n iterations, each O(1) = O(n) │
│ │
│ For 100 aliases: 100 operations (vs 4,950) │
│ │
└─────────────────────────────────────────────────────────────┘
2. get-remotes-for-host.ts - Optimized
┌─────────────────────────────────────────────────────────────┐
│ OPTIMIZATIONS │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Object.keys(x) │ ───► │ const keys = │ │
│ │ Object.keys(x) │ │ Object.keys(x)│ │
│ │ (2 calls) │ │ // use keys │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ r.replace(...) │ ───► │ const norm = │ │
│ │ r.replace(...) │ │ r.replace(...)│ │
│ │ (2 calls) │ │ // use norm │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Math.max( │ ───► │ for (port of p) │ │
│ │ ...[...a,...b] │ │ if (port>max) │ │
│ │ ) │ │ max = port │ │
│ │ (3 arrays) │ │ (0 extra arrays)│ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Why Accept This PR
- Significant complexity reduction: O(n²) → O(n) for path mappings processing
- Zero behavior change: Test passes, no functional changes
- Clean implementation: Simple refactoring using idiomatic patterns
- Complementary to PR #33734: Optimizes files not touched by that PR
Related Issue(s)
Performance improvement for Module Federation path mappings and remote resolution.
Merge Dependencies
This PR has no dependencies and can be merged independently.
Deploy request for nx-docs pending review.
Visit the deploys page to approve it
| Name | Link |
|---|---|
| Latest commit | fd35d4be4803f45f80577b92864854b2e335fdaa |
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Preview | Updated (UTC) |
|---|---|---|---|
| nx-dev | Preview | Dec 8, 2025 6:51am |
View your CI Pipeline Execution ↗ for commit fd35d4be4803f45f80577b92864854b2e335fdaa
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected --targets=lint,test,test-kt,build,e... |
✅ Succeeded | 7m 16s | View ↗ |
nx run-many -t check-imports check-lock-files c... |
✅ Succeeded | 2m 27s | View ↗ |
nx-cloud record -- nx-cloud conformance:check |
✅ Succeeded | 11s | View ↗ |
nx-cloud record -- nx format:check |
✅ Succeeded | 2s | View ↗ |
nx-cloud record -- nx sync:check |
✅ Succeeded | <1s | View ↗ |
☁️ Nx Cloud last updated this comment at 2025-12-12 17:57:12 UTC
This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.