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: ``,