[localization-plugin] Improve localized asset construction performance by 50% (#4862)

* [localization-plugin] Improve localized asset construction performance

* [localization-plugin] Revert reverse iteration

---------

Co-authored-by: David Michon <dmichon-msft@users.noreply.github.com>
This commit is contained in:
David Michon 2024-08-06 13:18:10 -07:00 коммит произвёл GitHub
Родитель 7e16111340
Коммит 5f751545b8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 27 добавлений и 13 удалений

Просмотреть файл

@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/webpack5-localization-plugin",
"comment": "Improve performance of localized asset reconstruction.",
"type": "patch"
}
],
"packageName": "@rushstack/webpack5-localization-plugin"
}

Просмотреть файл

@ -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;
@ -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;