diff --git a/tools/performance/measure-initial-bytes.mjs b/tools/performance/measure-initial-bytes.mjs
index 17f734c3c..c50c56a23 100644
--- a/tools/performance/measure-initial-bytes.mjs
+++ b/tools/performance/measure-initial-bytes.mjs
@@ -66,7 +66,17 @@ function classify(tag, attributes) {
* inline script element is still seen.
*/
export function stripInertHtml(html) {
- return html.replace(HTML_COMMENT, '').replace(INLINE_ELEMENT_BODY, '$1$3');
+ // Repeat until nothing changes: a single pass can expose a new comment or
+ // element body assembled from the pieces around a removed one.
+ let previous;
+ let stripped = html;
+ do {
+ previous = stripped;
+ stripped = stripped
+ .replace(HTML_COMMENT, '')
+ .replace(INLINE_ELEMENT_BODY, '$1$3');
+ } while (stripped !== previous);
+ return stripped;
}
/**
diff --git a/tools/performance/measure-initial-bytes.test.mjs b/tools/performance/measure-initial-bytes.test.mjs
index 6ba1b9e56..5857e6c4e 100644
--- a/tools/performance/measure-initial-bytes.test.mjs
+++ b/tools/performance/measure-initial-bytes.test.mjs
@@ -132,7 +132,13 @@ test('ignores commented-out tags and tag-like text inside inline scripts and sty
extractInitialResources(html).map((resource) => resource.url),
['assets/app-config.js', 'main.js']
);
- assert.equal(stripInertHtml(''), '');
+ assert.equal(stripInertHtml(''), ''); // Pieces around a removed comment must not assemble into a live tag.
+ assert.deepEqual(
+ extractInitialResources(
+ '-- -->'
+ ),
+ []
+ );
});
test('counts a file once per distinct request URL', async () => {