Минификация строк и литералов

Минификация представляет собой процесс сокращения объёма исходного кода без изменения его поведения. В контексте строк и литералов задача минификатора заключается не только в уменьшении количества символов, но и в выборе наиболее компактного представления данных.

В экосистеме JavaScript библиотека SWC выполняет подобные преобразования на этапе компиляции и оптимизации. Минификация строк и литералов особенно важна для крупных приложений, содержащих большое количество текстовых констант, регулярных выражений, числовых значений и шаблонных литералов.

Основные цели:

  • уменьшение размера итогового бандла;
  • снижение объёма передаваемых данных по сети;
  • сокращение времени загрузки страницы;
  • повышение эффективности последующего сжатия gzip и Brotli.

Литералы в JavaScript

Под литералами понимаются значения, непосредственно записанные в коде.

Примеры различных литералов:

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

Преимущества:

  • меньше размер;
  • гарантированно неизменяемое значение;
  • традиционный подход большинства JavaScript-минификаторов.

Оптимизация литерала 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 нигде больше не используется.


Влияние минификации на сжатие gzip и Brotli

Уменьшение числа символов полезно само по себе, однако основная выгода проявляется после дополнительного сетевого сжатия.

Исходный код:

const message = "Application loaded successfully";

После минификации:

const message="Application loaded successfully";

Экономия составляет всего несколько символов.

Но в проекте с тысячами подобных строк:

  • сокращается общий объём бандла;
  • повышается эффективность повторяющихся паттернов;
  • улучшается коэффициент сжатия gzip;
  • улучшается коэффициент сжатия Brotli.

Настройка минификации строк в SWC

Минификация включается через секцию 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 и позволяют эффективно сокращать объём строковых, числовых и других литералов ещё на этапе компиляции.