From 9a069b583a5926b16733a9a205f7a803b35d5c51 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:13:06 +0000 Subject: [PATCH] perf(@angular/build): optimize template string size calculation in server manifest Calculates normalized byte lengths for server assets directly using Node.js Buffer.byteLength to avoid script compilation with vm.runInThisContext. --- .../build/src/utils/server-rendering/manifest.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/utils/server-rendering/manifest.ts b/packages/angular/build/src/utils/server-rendering/manifest.ts index bd294b1e7e4b..1ee430a76333 100644 --- a/packages/angular/build/src/utils/server-rendering/manifest.ts +++ b/packages/angular/build/src/utils/server-rendering/manifest.ts @@ -7,8 +7,8 @@ */ import type { Metafile } from 'esbuild'; +import { Buffer } from 'node:buffer'; import { extname } from 'node:path'; -import { runInThisContext } from 'node:vm'; import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { type BuildOutputFile, @@ -174,9 +174,14 @@ export function generateAngularServerAppManifest( ), ); - // This is needed because JavaScript engines script parser convert `\r\n` to `\n` in template literals, - // which can result in an incorrect byte length. - const size = runInThisContext(`new TextEncoder().encode(\`${escapedContent}\`).byteLength`); + // JavaScript engine script parsers normalize `\r\n` (2 bytes in UTF-8) to `\n` (1 byte in UTF-8) in template literals. + // Subtracting the count of `\r\n` occurrences avoids allocating any temporary strings or match arrays for large assets. + let size = Buffer.byteLength(file.text); + let pos = file.text.indexOf('\r\n'); + while (pos !== -1) { + size--; + pos = file.text.indexOf('\r\n', pos + 2); + } serverAssets[file.path] = `{size: ${size}, hash: '${file.hash}', text: () => import('./${jsChunkFilePath}').then(m => m.default)}`;