Skip to content

Commit 6fafb26

Browse files
perf(html): mask HTML comments once per HMR evaluation
The extract shim masked the full HTML on every tag-boundary search (head/body/title + dispose). Precompute one masked copy per evaluation and reuse it, so a large page isn't re-scanned per section.
1 parent 0bc17fc commit 6fafb26

1 file changed

Lines changed: 18 additions & 17 deletions

File tree

lib/html/HtmlGenerator.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -460,39 +460,40 @@ class HtmlGenerator extends Generator {
460460
// otherwise stop at the FIRST `</body>` it sees, even one
461461
// inside a comment).
462462
'var __webpack_mask_comments__ = function (h) { return h.replace(/<!--[\\s\\S]*?-->/g, function (c) { return c.replace(/[^\\n]/g, " "); }); };',
463-
// Slice the inner content of `<tag>…</tag>` out of `h`,
464-
// using the masked copy only to locate the tag boundaries.
465-
"var __webpack_extract__ = function (h, tag) {",
463+
// Mask comments once per evaluation; reused for every
464+
// tag-boundary search (head/body/title and the dispose-time
465+
// head diff) so a large page isn't re-scanned per section.
466+
"var __webpack_masked_html__ = __webpack_mask_comments__(__webpack_html__);",
467+
// Slice the inner content of `<tag>…</tag>` out of the original
468+
// HTML, using the pre-masked copy to locate the tag boundaries.
469+
"var __webpack_extract__ = function (tag) {",
466470
Template.indent([
467-
"var masked = __webpack_mask_comments__(h);",
468-
'var open = new RegExp("<" + tag + "[^>]*>", "i").exec(masked);',
471+
'var open = new RegExp("<" + tag + "[^>]*>", "i").exec(__webpack_masked_html__);',
469472
"if (!open) return null;",
470473
"var start = open.index + open[0].length;",
471-
'var close = new RegExp("</" + tag + ">", "i").exec(masked.slice(start));',
474+
'var close = new RegExp("</" + tag + ">", "i").exec(__webpack_masked_html__.slice(start));',
472475
"if (!close) return null;",
473-
"return h.slice(start, start + close.index);"
476+
"return __webpack_html__.slice(start, start + close.index);"
474477
]),
475478
"};",
476-
"var __webpack_extract_head__ = function (h) {",
479+
"var __webpack_extract_head__ = function () {",
477480
Template.indent([
478-
// Extract from the original HTML (`__webpack_extract__` masks
479-
// for boundary detection itself), then mask only the small
480-
// extracted head so a comment-only head edit doesn't force a
481-
// full reload — avoids re-masking the whole document.
482-
'var head = __webpack_extract__(h, "head");',
481+
// Mask only the small extracted head so a comment-only head
482+
// edit doesn't force a full reload.
483+
'var head = __webpack_extract__("head");',
483484
'return head === null ? "" : __webpack_mask_comments__(head).replace(/<title[^>]*>[\\s\\S]*?<\\/title>/i, "").trim();'
484485
]),
485486
"};",
486487
"if (module.hot.data && typeof document !== 'undefined') {",
487488
Template.indent([
488-
"var __webpack_new_head__ = __webpack_extract_head__(__webpack_html__);",
489+
"var __webpack_new_head__ = __webpack_extract_head__();",
489490
"if (module.hot.data.__webpack_head__ !== undefined && __webpack_new_head__ !== module.hot.data.__webpack_head__ && typeof window !== 'undefined' && window.location && typeof window.location.reload === 'function') {",
490491
Template.indent("window.location.reload();"),
491492
"} else {",
492493
Template.indent([
493-
'var __webpack_body__ = __webpack_extract__(__webpack_html__, "body");',
494+
'var __webpack_body__ = __webpack_extract__("body");',
494495
"if (__webpack_body__ !== null && document.body) document.body.innerHTML = __webpack_body__;",
495-
'var __webpack_title__ = __webpack_extract__(__webpack_html__, "title");',
496+
'var __webpack_title__ = __webpack_extract__("title");',
496497
"if (__webpack_title__ !== null) document.title = __webpack_title__;"
497498
]),
498499
"}"
@@ -501,7 +502,7 @@ class HtmlGenerator extends Generator {
501502
// Capture this evaluation's head (sans title, comments
502503
// masked) on dispose so the next module instance can diff
503504
// against it.
504-
"module.hot.dispose(function (data) { data.__webpack_head__ = __webpack_extract_head__(__webpack_html__); });"
505+
"module.hot.dispose(function (data) { data.__webpack_head__ = __webpack_extract_head__(); });"
505506
]
506507
: ["module.hot.accept();"];
507508
return Template.asString([

0 commit comments

Comments
 (0)