refactor(@angular/build): budget and optimize JavaScript transformation concurrency - #34086
Open
clydin wants to merge 4 commits into
Open
refactor(@angular/build): budget and optimize JavaScript transformation concurrency#34086clydin wants to merge 4 commits into
clydin wants to merge 4 commits into
Conversation
…Transformer Aligns the JavaScriptTransformer concurrency configuration and semantics with the I18nInliner API. An optional maxConcurrency property is added to JavaScriptTransformerOptions with validation to ensure it is an integer greater than or equal to 1. The required positional maxThreads parameter is removed from the constructor, allowing concurrency to default to the available worker pool threads when omitted. The previous concurrency multiplier that allowed up to double the worker count in active transformation tasks has also been removed. With the significantly faster oxc-based transformation pipeline, individual file transformations complete in milliseconds, eliminating the need for deep I/O task pre-buffering. Bounding active tasks directly to maxConcurrency also prevents task bursts from prematurely forcing the worker pool to expand to its maximum thread count. The minThreads pinning in WorkerPool creation is removed so that Piscina defaults to a single initial thread instead of eagerly allocating all workers.
…hrottle Ensures that direct calls to transformData are bounded by the concurrency throttle. Previously, transformData bypassed the semaphore and directly dispatched tasks to the worker pool. A private #transform method now contains the core transformation logic, allowing both transformFile and transformData to use the throttle without double-throttling or unbounded worker dispatch.
…currency during bundling JavaScript transformation tasks with the OXC linker are very fast (roughly 10ms per file), whereas worker thread startup in Node.js costs around 140ms per thread. Concurrently, esbuild utilizes all available CPU cores for bundling. Budgeting transformation concurrency to a quarter of available cores balances parallel processing capacity with thread startup costs and avoids starving esbuild. A minimum of 1 ensures transformation progress on small or constrained environments, while an upper bound of 6 accommodates large builds on many-core systems without inducing thread scheduling overhead or excessive memory footprint.
There was a problem hiding this comment.
Code Review
This pull request refactors the JavaScriptTransformer class to accept a maxConcurrency option within its configuration object, replacing the previous positional maxThreads argument. It also introduces a new maxTransformWorkers utility to calculate the default transformation concurrency based on available parallelism (capped at 6) to prevent CPU starvation during bundling. Unit tests have been updated and expanded to cover these changes. No review comments were provided, so there is no feedback to address.
…avaScriptTransformer Worker thread startup in Node.js incurs a non-trivial initialization delay (roughly 100ms to 160ms) primarily driven by V8 module evaluation and loading transitive dependencies of the linker, such as @angular/compiler-cli, @angular/compiler, and TypeScript. While individual OXC file transformations take only around 10ms, on-demand thread creation during burst requests exposes this startup latency directly on the critical path. Configuring minThreads to match maxConcurrency ensures that worker threads are pre-allocated upfront. During initial bundling, this allows workers to complete their initialization concurrently while TypeScript compilation executes, hiding module loading overhead and preventing transformation bottlenecks when esbuild emits files. If linker initialization costs are reduced in the future or a pre-warmed shared worker pool is introduced, this pre-allocation strategy can be revisited.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Optimizes JavaScript transformation concurrency and aligns the
JavaScriptTransformerconfiguration and throttling semantics with the rest of the build pipeline (specificallyI18nInliner).With the OXC-based linker, JavaScript transformation tasks are significantly faster (completing in milliseconds per file), whereas worker thread instantiation in Node.js incurs ~140ms overhead per thread. Concurrently, esbuild utilizes all available CPU cores for bundling. This change budgets transformation concurrency to balance parallel processing capacity against thread startup and scheduling overhead, and ensures transformation backpressure is applied consistently across all entry points.