Skip to content

perf(@angular/build): traverse AST with iterative post-order walker in i18n inliner - #33845

Open
clydin wants to merge 1 commit into
angular:mainfrom
clydin:perf-i18n-inliner-post-order-walk
Open

perf(@angular/build): traverse AST with iterative post-order walker in i18n inliner#33845
clydin wants to merge 1 commit into
angular:mainfrom
clydin:perf-i18n-inliner-post-order-walk

Conversation

@clydin

@clydin clydin commented Aug 12, 2026

Copy link
Copy Markdown
Member

Replace the oxc-parser Visitor class in the i18n inliner worker with a lightweight, non-recursive post-order AST walker based on visitorKeys.

oxc-parser's Visitor class caches visitor callback objects in a module-global array across invocations, which causes all per-request MagicString instances, source code buffers, and diagnostics closures to be retained for the lifetime of the worker thread. In multi-locale builds, this leads to continuous heap accumulation and out-of-memory errors on memory-constrained CI runners.

The custom walker uses an iterative two-pass array traversal on the V8 heap to guarantee bottom-up evaluation without recursion or stack overflow risks. This ensures nested $localize template expressions are transformed and written to MagicString before outer templates evaluate their expressions, while eliminating all module-global caching and memory retention across file transformations.

@angular-robot angular-robot Bot added area: performance Issues related to performance area: @angular/build labels Aug 12, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request replaces the recursive Visitor from oxc-parser with a custom non-recursive post-order AST traversal function (walkAstPostOrder) in the i18n inliner worker. This bottom-up traversal ensures that nested $localize expressions are correctly processed before their outer containing templates. A unit test has also been added to verify this behavior. The feedback suggests optimizing the AST walker by flattening array children directly when pushing them onto the stack, which simplifies the loop logic and allows for stricter typing of the traversal stack.

Comment thread packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts
@clydin
clydin force-pushed the perf-i18n-inliner-post-order-walk branch 2 times, most recently from f9c75b7 to bc2a9dc Compare August 12, 2026 14:24
…n i18n inliner

Replace the oxc-parser Visitor class in the i18n inliner worker with a lightweight, non-recursive post-order AST walker based on visitorKeys.

oxc-parser's Visitor class caches visitor callback objects in a module-global array across invocations, which causes all per-request MagicString instances, source code buffers, and diagnostics closures to be retained for the lifetime of the worker thread. In multi-locale builds, this leads to continuous heap accumulation and out-of-memory errors on memory-constrained CI runners.

The custom walker uses an iterative two-pass array traversal on the V8 heap to guarantee bottom-up evaluation without recursion or stack overflow risks. This ensures nested $localize template expressions are transformed and written to MagicString before outer templates evaluate their expressions, while eliminating all module-global caching and memory retention across file transformations.
@clydin
clydin force-pushed the perf-i18n-inliner-post-order-walk branch from bc2a9dc to 502ee51 Compare August 12, 2026 14:26
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Aug 12, 2026
@clydin
clydin requested a review from alan-agius4 August 12, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/build area: performance Issues related to performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant