Skip to content

Commit

Permalink
[localization-plugin] Improve localized asset construction performanc…
Browse files Browse the repository at this point in the history
…e by 50% (#4862)

* [localization-plugin] Improve localized asset construction performance

* [localization-plugin] Revert reverse iteration

---------

Co-authored-by: David Michon <[email protected]>
  • Loading branch information
dmichon-msft and dmichon-msft authored Aug 6, 2024
1 parent 7e16111 commit 5f75154
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/webpack5-localization-plugin",
"comment": "Improve performance of localized asset reconstruction.",
"type": "patch"
}
],
"packageName": "@rushstack/webpack5-localization-plugin"
}
30 changes: 17 additions & 13 deletions webpack/webpack5-localization-plugin/src/AssetProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,19 +228,25 @@ function _reconstructLocalized(

const escapedBackslash: string = element.escapedBackslash || '\\';

// Replace backslashes with the properly escaped backslash
BACKSLASH_REGEX.lastIndex = -1;
newValue = newValue.replace(BACKSLASH_REGEX, escapedBackslash);

// @todo: look into using JSON.parse(...) to get the escaping characters
const escapingCharacterSequence: string = escapedBackslash.slice(escapedBackslash.length / 2);
if (newValue.includes('\\')) {
// The vast majority of localized strings do not contain `\\`, so this check avoids an allocation.
// Replace backslashes with the properly escaped backslash
BACKSLASH_REGEX.lastIndex = -1;
newValue = newValue.replace(BACKSLASH_REGEX, escapedBackslash);
}

// Ensure the the quotemark, apostrophe, tab, and newline characters are properly escaped
ESCAPE_REGEX.lastIndex = -1;
newValue = newValue.replace(
ESCAPE_REGEX,
(match) => `${escapingCharacterSequence}${ESCAPE_MAP.get(match)}`
);
if (ESCAPE_REGEX.test(newValue)) {
// The majority of localized strings do not contain the characters that need to be escaped,
// so this check avoids an allocation.
// @todo: look into using JSON.parse(...) to get the escaping characters
const escapingCharacterSequence: string = escapedBackslash.slice(escapedBackslash.length / 2);
newValue = newValue.replace(
ESCAPE_REGEX,
(match) => `${escapingCharacterSequence}${ESCAPE_MAP.get(match)}`
);
}

result.replace(element.start, element.end - 1, newValue);
break;
Expand Down Expand Up @@ -305,9 +311,7 @@ function _parseStringToReconstructionSequence(
const jsonStringifyFormatLocaleForFilenameFn: FormatLocaleForFilenameFn = (locale: string) =>
JSON.stringify(formatLocaleForFilenameFn(locale));

let regexResult: RegExpExecArray | null;
PLACEHOLDER_REGEX.lastIndex = -1;
while ((regexResult = PLACEHOLDER_REGEX.exec(source))) {
for (const regexResult of source.matchAll(PLACEHOLDER_REGEX)) {
const [placeholder, escapedBackslash, elementLabel, placeholderSerialNumber] = regexResult;
const start: number = regexResult.index;
const end: number = start + placeholder.length;
Expand Down

0 comments on commit 5f75154

Please sign in to comment.