Минификация представляет собой процесс сокращения объёма исходного кода без изменения его поведения. В контексте строк и литералов задача минификатора заключается не только в уменьшении количества символов, но и в выборе наиболее компактного представления данных.
В экосистеме JavaScript библиотека SWC выполняет подобные преобразования на этапе компиляции и оптимизации. Минификация строк и литералов особенно важна для крупных приложений, содержащих большое количество текстовых констант, регулярных выражений, числовых значений и шаблонных литералов.
Основные цели:
Под литералами понимаются значения, непосредственно записанные в коде.
Примеры различных литералов:
"Hello"
&
42
3.14
true
false
null
[1, 2, 3]
{
name: "John"
}
`Template string`
Во время минификации SWC анализирует подобные конструкции и пытается представить их в максимально компактном виде.
JavaScript допускает использование одинарных и двойных кавычек:
const a = "hello";
const b = 'hello';
Если внутри строки содержатся двойные кавычки, использование одинарных может уменьшить количество экранирований:
Исходный код:
const text = "User said \"Hello\"";
После оптимизации:
const text='User said "Hello"';
Количество символов уменьшается за счёт удаления обратных слэшей.
Избыточное экранирование увеличивает размер файла.
Исходный вариант:
const path = "C:\\\\temp\\\\files";
После обработки:
const path="C:\\temp\\files";
SWC сохраняет только обязательные экранирования.
Некоторые символы допускают несколько форм записи.
Пример:
const str = "\x0A";
Может быть преобразован в:
const str="\n";
Если альтернативное представление короче, минификатор отдаёт предпочтение ему.
Шаблонные строки обладают более сложной структурой:
const text = `Hello ${name}`;
SWC анализирует необходимость использования шаблонного литерала.
Если интерполяция отсутствует:
const text = `Hello`;
возможна замена на обычную строку:
const text="Hello";
Размер кода уменьшается, а выполнение становится немного проще для движка JavaScript.
Исходный код:
const text = `${name}`;
После минификации:
const text=name+"";
или
const text=String(name);
Конкретный результат зависит от настроек и версии оптимизатора.
Цель подобных преобразований — получение более компактного представления.
Исходный код:
const message = `Hello ${name}!`;
При наличии дополнительных оптимизаций может быть получено:
const message="Hello "+name+"!";
Если такая форма оказывается короче.
Числа часто занимают значительную долю кода, особенно в графике, анимации и математических вычислениях.
SWC умеет выбирать наиболее компактную форму записи.
Исходный код:
const value = 0.5;
После минификации:
const value=.5;
JavaScript корректно интерпретирует обе записи.
Большие и очень маленькие числа могут быть представлены короче.
Исходный вариант:
const size = 1000000;
После оптимизации:
const size=1e6;
Другой пример:
const value = 0.000001;
Преобразуется в:
const value=1e-6;
Исходный код:
const value = 10.000;
После минификации:
const value=10;
Поскольку числовое значение остаётся неизменным, такое преобразование полностью безопасно.
Логические значения представлены ключевыми словами:
true
false
Непосредственно сократить их невозможно, однако SWC способен применять контекстные оптимизации.
Пример:
if (true) {
run();
}
После свёртки констант:
run();
Литерал исчезает полностью.
Другой пример:
if (false) {
run();
}
После оптимизации:
Недостижимый код удаляется.
undefined
Во многих случаях запись:
undefined
может быть заменена более короткой формой.
Исходный код:
const value = undefined;
После минификации:
const value=void 0;
Преимущества:
Infinity
Исходный вариант:
const max = Infinity;
В некоторых случаях возможно преобразование:
const max=1/0;
Минификатор выбирает наиболее короткое представление.
NaN
Исходный код:
const value = NaN;
Возможный результат:
const value=0/0;
Подобные преобразования зависят от настроек компрессии и оценки итогового размера кода.
Регулярные выражения являются отдельным видом литералов:
const re = /abc/;
SWC способен выполнять ограничённые оптимизации таких конструкций.
Исходный вариант:
/(abc)/
После упрощения:
/abc/
Если группа не влияет на результат поиска.
Исходный код:
/[0-9]/
Может быть преобразован в:
/\d/
Если это уменьшает размер выражения.
Исходное выражение:
/\-/
После оптимизации:
/-/
Когда экранирование не требуется.
SWC способен вычислять выражения ещё до выполнения программы.
Исходный код:
const text = "Hello" + " " + "World";
После свёртки:
const text="Hello World";
Подобная оптимизация называется constant folding.
Другой пример:
const value = "A" + "B" + "C";
После обработки:
const value="ABC";
Исходный код:
const message = `Hello ${"World"}`;
После вычисления:
const message="Hello World";
Поскольку результат известен во время компиляции, интерполяция становится ненужной.
Рассмотрим пример:
const prefix = "api/";
const route = prefix + "users";
После анализа зависимостей возможно получение:
const route="api/users";
При условии, что значение prefix нигде больше не
используется.
Уменьшение числа символов полезно само по себе, однако основная выгода проявляется после дополнительного сетевого сжатия.
Исходный код:
const message = "Application loaded successfully";
После минификации:
const message="Application loaded successfully";
Экономия составляет всего несколько символов.
Но в проекте с тысячами подобных строк:
Минификация включается через секцию jsc.minify.
Пример конфигурации:
{
"jsc": {
"minify": {
"compress": true,
"mangle": true
}
}
}
Либо более подробно:
{
"jsc": {
"minify": {
"compress": {
"evaluate": true,
"unsafe": false
},
"mangle": true
}
}
}
Ключевые параметры:
| Параметр | Назначение |
|---|---|
| compress | Включает оптимизацию литералов и выражений |
| evaluate | Выполняет вычисление констант |
| mangle | Сокращает имена переменных |
| unsafe | Разрешает дополнительные рискованные преобразования |
Не каждое преобразование является безопасным.
Например:
const value = "\u2028";
и
const value = "
";
могут вести себя по-разному в старых средах выполнения.
Поэтому SWC придерживается консервативного подхода и выполняет только гарантированно безопасные преобразования, если явно не включены дополнительные агрессивные оптимизации.
Исходный код:
const version = "1." + "0." + "0";
const timeout = 1000000;
const enabled = true;
const message = `Version: ${version}`;
if (enabled) {
console.log(message);
}
После минификации и свёртки констант:
const version="1.0.0",timeout=1e6,message="Version: 1.0.0";console.log(message);
Выполнены следующие преобразования:
true;
Подобные оптимизации являются одним из ключевых механизмов уменьшения размера JavaScript-бандлов при использовании SWC и позволяют эффективно сокращать объём строковых, числовых и других литералов ещё на этапе компиляции.