Skip to content

angular-rspack: poor local dev incremental build performance #34936

@Timebutt

Description

@Timebutt

Current Behavior

I'd like to post a follow-up issue of this GitHub issue. The discussion in that issue is closed, but there are more performance issues lingering in the current rspack-angular implementation that I feel should be addressed.

I'm currently in the process of switching a big Nx project from the legacy Angular webpack builder to the new Rspack based approach. Migration proved easy, despite having multiple custom plugins and an intricate module federation setup. One important open issue caused issues however, the patch-package fix in this open GitHub PR addressed the problem.

My problems started to appear whenever I started testing out the local development flow with the @nx/rspack-angular plugin. I noticed terrible rebuild performance and started investigating. I was very happy to see the original GitHub issue mentioned earlier, thinking the latest Nx version (22.4+) would address my issues but that does not seem to be the case. The performance improvements recently released might be very helpful, but I think there is still something very off in the incremental build flow that seriously hampers performance.

When running the local dev server for a few large Angular applications, I noticed Rspack was at times 2x/3x slower than Webpack when making changes! This, while the initial build for the local server can be 5x/6x faster than using webpack. The original issue also mentions people noticing the rebuild times get much longer as the application scales, which is one of the things I've noticed as well.

I can't share the codebase I'm experiencing this in, but I modified the ng-bundler-benchmar repo @Coly010 created to benchmark the build times of different bundlers to include a setup that allows one to serve the application using webpack, esbuild and rspack. The branch add-local-dev-configurations of my fork of that repo is just that.

The example does not entirely reproduce the major slowdown in rebuild times I'm seeing in my enterprise grade application, but does show a few things:

  • Incremental builds in webpack are faster than when using rspack (3s for webpack vs 4-6s on my MacBook pro)
  • Incremental builds for rspack seem to trigger recompiling twice. The original issue had an MR to fix this issue, but it seems the debounce time is not sufficient for this repo, or something else is going on
  • When changing a single file, rspack continuously outputs a list of every (!) chunk in the compilation, hinting at the fact that rspack is probably recompiling everything whenever a single file changes (which would explain the massive slowdown related to repo size)
  • Oddly enough, the esbuild dev server isn't doing much better for this repo for some reason in terms of rebuild times. The enterprise application I'm working on is very different in this regard, rebuilds are 6s for webpack, 8s for rspack and 1s for esbuild. I can't get the same build speed improvement using esbuild for the ng-bundler-benchmark repo though ...

I've meanwhile done lots of investigation and digging into the inner workings of the plugin, but so far can't distinguish yet what the root cause of the issue is. It looks like on rebuild, the right list of changed files is passed into the compilation, but from everything I'm seeing it looks like nothing is cached and an incremental build is basically a rebuild. I can't pinpoint the issue yet, but maybe I can help someone with more experience debug the issue faster?

I've unleashed Opus 4.6 at the plugin with all of the context above, and it did uncover this issue which it claims might trigger every file to be compiled all the time:

The root cause is in setupCompilationWithAngularCompilation. On every rebuild in watch mode, it calls setupCompilation(config, options):


setup-with-angular-compilation.ts
packages/angular-rspack-compiler/src/compilation
This creates a brand-new ComponentStylesheetBundler on every single rebuild:


setup-compilation.ts
packages/angular-rspack-compiler/src/compilation
That new bundler has an empty cache, so when angularCompilation.initialize receives the new transformStylesheet function wrapping it, the Angular compilation has to re-transform every component's inline/external styles from scratch. This causes emitAffectedFiles() (called in buildAndAnalyze) to re-emit all files — not just the one you changed — because all style outputs are "new" from the compilation's perspective. Rspack then sees every module in the typescriptFileCache as updated, marks every chunk as rendered: true, and the stats logger in statsToString dutifully logs them all (it only filters out chunks with rendered: false on subsequent builds).

In short: one file changes → style bundler is recreated with no cache → all components re-emit → all chunks re-render → all chunks are logged.

I will continue investigating to try and provide a fix but I fear I'm missing something crucial in the inner workings of the compilation setup. Would be great to spar with someone else with more insight into this ;) The rspack-angular plugin is wonderful and I would love to migrate our entire code base to it, but I cannot do so because the local dev experience is even worse off than good 'ol webpack for us D:

Hoping this gets us on a path to a fast local dev rspack-angular plugin!

Expected Behavior

Rebuild should be (much) faster than webpack when running the local dev server

GitHub Repo

https://github.com/Timebutt/ng-bundler-benchmark/tree/add-local-dev-configurations

Steps to Reproduce

  1. Run npx nx run esbuild:serve-rspack and observe rebuild times (first rebuild is always slow). Rebuilds also trigger two compilation steps. Also see that the terminal list every single chunk for every rebuild, hinting at the fact that probably every single chunk is recompiled on save?
  2. Now run npx nx run esbuild:serve-webpack and observe rebuild times are actually faster than in the rspack case. For webpack only one chunk is listed when a change is made to a component

Nx Report

NX   Report complete - copy this into the issue template

Node           : 25.1.0
OS             : darwin-arm64
Native Target  : aarch64-macos
pnpm           : 9.15.2
daemon         : Available

nx                     : 22.5.4
@nx/js                 : 22.5.4
@nx/eslint             : 22.5.4
@nx/workspace          : 22.5.4
@nx/angular            : 22.5.4
@nx/devkit             : 22.5.4
@nx/eslint-plugin      : 22.5.4
@nx/module-federation  : 22.5.4
@nx/rspack             : 22.5.4
@nx/web                : 22.5.4
@nx/webpack            : 22.5.4
typescript             : 5.9.3
---------------------------------------
Community plugins:
angular-eslint : 21.3.0
---------------------------------------
Cache Usage: 0.00 B / 92.64 GB

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

No response

Metadata

Metadata

Labels

priority: highHigh Priority (important issues which affect many people severely)scope: angularIssues related to Angular support in Nxtype: bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions