Skip to content

Commit 6ff2f3e

Browse files
committed
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.
1 parent 3c7ac15 commit 6ff2f3e

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

  • packages/angular/build/src/utils/server-rendering

packages/angular/build/src/utils/server-rendering/manifest.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import type { Metafile } from 'esbuild';
1010
import { extname } from 'node:path';
11-
import { runInThisContext } from 'node:vm';
1211
import { NormalizedApplicationBuildOptions } from '../../builders/application/options';
1312
import {
1413
type BuildOutputFile,
@@ -174,9 +173,14 @@ export function generateAngularServerAppManifest(
174173
),
175174
);
176175

177-
// This is needed because JavaScript engines script parser convert `\r\n` to `\n` in template literals,
178-
// which can result in an incorrect byte length.
179-
const size = runInThisContext(`new TextEncoder().encode(\`${escapedContent}\`).byteLength`);
176+
// JavaScript engine script parsers normalize `\r\n` (2 bytes in UTF-8) to `\n` (1 byte in UTF-8) in template literals.
177+
// Subtracting the count of `\r\n` occurrences avoids allocating any temporary strings or match arrays for large assets.
178+
let size = Buffer.byteLength(file.text);
179+
let pos = file.text.indexOf('\r\n');
180+
while (pos !== -1) {
181+
size--;
182+
pos = file.text.indexOf('\r\n', pos + 2);
183+
}
180184

181185
serverAssets[file.path] =
182186
`{size: ${size}, hash: '${file.hash}', text: () => import('./${jsChunkFilePath}').then(m => m.default)}`;

0 commit comments

Comments
 (0)