diff --git a/docs/architecture/performance-journeys.md b/docs/architecture/performance-journeys.md
index bde842eb0..4e1a35629 100644
--- a/docs/architecture/performance-journeys.md
+++ b/docs/architecture/performance-journeys.md
@@ -32,16 +32,19 @@ The bytes a browser fetches before Angular can bootstrap, read from the built
- every ``,
- every `` chunk.
-Manifest, icons, external URLs and lazy chunks are not counted. A file that
-`index.html` references but the build did not emit is an error, never zero
-bytes. The value is raw (uncompressed) size, which is what the renderer parses;
-it matches the "Initial total" line of the Angular build output.
+Manifest, icons, external URLs, commented-out tags and lazy chunks are not
+counted. A file that `index.html` references but the build did not emit is an
+error, never zero bytes. The value is raw (uncompressed) size, which is what the
+renderer parses. It is Angular's "Initial total" plus `index.html` and
+`assets/app-config.js` (about 4 KB together), so it sits slightly above the
+rounded figure the build prints; never copy that figure into a baseline, use
+the script's output.
```bash
-pnpm nx build web # production configuration
-pnpm run perf:initial-bytes # human-readable breakdown
-pnpm run perf:initial-bytes -- --json # machine-readable breakdown
-pnpm run perf:initial-bytes -- --summary dist/performance/journey-summary.json
+pnpm nx build web # production configuration
+pnpm run perf:initial-bytes # human-readable breakdown
+pnpm --silent run perf:initial-bytes -- --json # machine-readable; --silent keeps pnpm's headers out of stdout
+node tools/performance/measure-initial-bytes.mjs --summary dist/performance/journey-summary.json
```
`--summary` writes the journey summary shape (`journeys..counters`)
diff --git a/tools/performance/measure-initial-bytes.mjs b/tools/performance/measure-initial-bytes.mjs
index c3cb6067f..17f734c3c 100644
--- a/tools/performance/measure-initial-bytes.mjs
+++ b/tools/performance/measure-initial-bytes.mjs
@@ -21,6 +21,8 @@ export const INITIAL_BYTES_COUNTER = 'renderer.initialBytes';
export const LAUNCH_JOURNEY = 'launch';
const TAG_PATTERN = /<(script|link)\b([^>]*)>/gi;
+const HTML_COMMENT = //g;
+const INLINE_ELEMENT_BODY = /(<(script|style)\b[^>]*>)[\s\S]*?(<\/\2\s*>)/gi;
const ATTRIBUTE_PATTERN =
/([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
const EXTERNAL_URL = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
@@ -56,6 +58,17 @@ function classify(tag, attributes) {
return null;
}
+/**
+ * Removes the parts of the document the browser never treats as markup: HTML
+ * comments (a commented-out ` -->
+
+
+
+
+ `;
+ assert.deepEqual(
+ extractInitialResources(html).map((resource) => resource.url),
+ ['assets/app-config.js', 'main.js']
+ );
+ assert.equal(stripInertHtml(''), '');
+});
+
test('counts a file once per distinct request URL', async () => {
const distDir = await writeDist('cache-busted', {
indexHtml: ``,