From 3deb68f2fad62c92725bf05a301397c282129246 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:27:45 -0400 Subject: [PATCH 1/2] perf(@angular/build): avoid loading compiler-cli and typescript in js transform worker Previously, `OxcLinker` imported `ConsoleLogger` and `LogLevel` directly from `@angular/compiler-cli`. Even though `@angular/compiler-cli/linker` is an isolated, lightweight runtime (depending only on `semver` and `convert-source-map`), resolving the main `@angular/compiler-cli` entry point (`bundles/index.js`) eagerly evaluated the full `ngtsc` compiler toolchain and required the 10 MB `typescript.js` bundle at the top level. As a result, every worker isolate in the JavaScript transformer pool unnecessarily loaded TypeScript and 50+ compiler modules upon bootstrap, incurring ~150 ms of startup CPU latency and allocating ~12 MB of heap per worker thread. --- .../src/tools/angular/linker/oxc-linker.ts | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts index 26133a6b5611..90cd1ea075ef 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { ConsoleLogger, LogLevel } from '@angular/compiler-cli'; +import type { Logger } from '@angular/compiler-cli'; import { type DeclarationScope, FileLinker, LinkerEnvironment } from '@angular/compiler-cli/linker'; import type { AbsoluteFsPath, @@ -45,7 +45,23 @@ const noopFileSystem: ReadonlyFileSystem = { relative: (_from: string, to: string) => to, } as unknown as ReadonlyFileSystem; -let SHARED_LOGGER: ConsoleLogger; +const defaultLogger: Logger = { + level: 1, // LogLevel.info + debug() {}, + info(...args: string[]) { + // eslint-disable-next-line no-console + console.info(...args); + }, + warn(...args: string[]) { + // eslint-disable-next-line no-console + console.warn(...args); + }, + error(...args: string[]) { + // eslint-disable-next-line no-console + console.error(...args); + }, +}; + let SHARED_AST_HOST: OxcAstHost; let SHARED_DECLARATION_SCOPE: InlineDeclarationScope; @@ -56,14 +72,13 @@ export class OxcLinker { readonly #fileLinker: FileLinker; constructor(filename: string, code: string, jit = false) { - SHARED_LOGGER ??= new ConsoleLogger(LogLevel.info); SHARED_AST_HOST ??= new OxcAstHost(); SHARED_DECLARATION_SCOPE ??= new InlineDeclarationScope(); const astFactory = new StringAstFactory(code); const linkerEnvironment = LinkerEnvironment.create( noopFileSystem, - SHARED_LOGGER, + defaultLogger, SHARED_AST_HOST, astFactory, { linkerJitMode: jit, sourceMapping: false }, From 0594016006fd9db08fa8b916d97ae90a72a01f97 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:36:16 -0400 Subject: [PATCH 2/2] fixup! perf(@angular/build): avoid loading compiler-cli and typescript in js transform worker --- .../src/tools/angular/linker/oxc-linker.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts index 90cd1ea075ef..8870fe1cc7da 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts @@ -47,18 +47,29 @@ const noopFileSystem: ReadonlyFileSystem = { const defaultLogger: Logger = { level: 1, // LogLevel.info - debug() {}, + debug(...args: string[]) { + if (this.level <= 0) { + // eslint-disable-next-line no-console + console.debug(...args); + } + }, info(...args: string[]) { - // eslint-disable-next-line no-console - console.info(...args); + if (this.level <= 1) { + // eslint-disable-next-line no-console + console.info(...args); + } }, warn(...args: string[]) { - // eslint-disable-next-line no-console - console.warn(...args); + if (this.level <= 2) { + // eslint-disable-next-line no-console + console.warn(...args); + } }, error(...args: string[]) { - // eslint-disable-next-line no-console - console.error(...args); + if (this.level <= 3) { + // eslint-disable-next-line no-console + console.error(...args); + } }, };