Skip to content

Commit b84efe6

Browse files
authored
Merge pull request #16759 from ryanwilsonperkin/real-content-hash-regex-perf
Improve performance of hashRegExp lookup
2 parents c98e9e0 + cfdb1df commit b84efe6

File tree

1 file changed

+44
-14
lines changed

1 file changed

+44
-14
lines changed

lib/optimize/RealContentHashPlugin.js

+44-14
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,43 @@ class RealContentHashPlugin {
178178
}
179179
}
180180
if (hashToAssets.size === 0) return;
181-
const hashRegExp = new RegExp(
182-
Array.from(hashToAssets.keys(), quoteMeta).join("|"),
183-
"g"
181+
const hashRegExps = Array.from(hashToAssets.keys(), quoteMeta).map(
182+
hash => new RegExp(hash, "g")
184183
);
184+
185+
/**
186+
* @param {string} str string to be matched against all hashRegExps
187+
* @returns {string[] | null} matches found
188+
*/
189+
const hashMatch = str => {
190+
/** @type {string[]} */
191+
const results = [];
192+
for (const hashRegExp of hashRegExps) {
193+
const matches = str.match(hashRegExp);
194+
if (matches) {
195+
matches.forEach(match => results.push(match));
196+
}
197+
}
198+
if (results.length) {
199+
return results;
200+
} else {
201+
return null;
202+
}
203+
};
204+
205+
/**
206+
* @param {string} str string to be replaced with all hashRegExps
207+
* @param {function(string): string} fn replacement function to use when a hash is found
208+
* @returns {string} replaced content
209+
*/
210+
const hashReplace = (str, fn) => {
211+
let result = str;
212+
for (const hashRegExp of hashRegExps) {
213+
result = result.replace(hashRegExp, fn);
214+
}
215+
return result;
216+
};
217+
185218
await Promise.all(
186219
assetsWithInfo.map(async asset => {
187220
const { name, source, content, hashes } = asset;
@@ -198,7 +231,7 @@ class RealContentHashPlugin {
198231
await cacheAnalyse.providePromise(name, etag, () => {
199232
const referencedHashes = new Set();
200233
let ownHashes = new Set();
201-
const inContent = content.match(hashRegExp);
234+
const inContent = hashMatch(content);
202235
if (inContent) {
203236
for (const hash of inContent) {
204237
if (hashes.has(hash)) {
@@ -298,7 +331,7 @@ ${referencingAssets
298331
identifier,
299332
etag,
300333
() => {
301-
const newContent = asset.content.replace(hashRegExp, hash =>
334+
const newContent = hashReplace(asset.content, hash =>
302335
hashToNewHash.get(hash)
303336
);
304337
return new RawSource(newContent);
@@ -323,15 +356,12 @@ ${referencingAssets
323356
identifier,
324357
etag,
325358
() => {
326-
const newContent = asset.content.replace(
327-
hashRegExp,
328-
hash => {
329-
if (asset.ownHashes.has(hash)) {
330-
return "";
331-
}
332-
return hashToNewHash.get(hash);
359+
const newContent = hashReplace(asset.content, hash => {
360+
if (asset.ownHashes.has(hash)) {
361+
return "";
333362
}
334-
);
363+
return hashToNewHash.get(hash);
364+
});
335365
return new RawSource(newContent);
336366
}
337367
);
@@ -374,7 +404,7 @@ ${referencingAssets
374404
await Promise.all(
375405
assetsWithInfo.map(async asset => {
376406
await computeNewContent(asset);
377-
const newName = asset.name.replace(hashRegExp, hash =>
407+
const newName = hashReplace(asset.name, hash =>
378408
hashToNewHash.get(hash)
379409
);
380410

0 commit comments

Comments
 (0)