Расширенные параметры: assumptions

В системе трансформации JavaScript/TypeScript кода в SWC параметр assumptions используется для задания набора логических предположений о поведении исходной среды выполнения. Эти предположения позволяют компилятору выполнять более агрессивные оптимизации, уменьшая объём генерируемого кода и повышая его производительность.

SWC работает как статический преобразователь AST, и многие преобразования в нём зависят от того, насколько строго он должен сохранять семантику JavaScript. Без дополнительных предположений трансформации вынуждены учитывать максимально широкий спектр крайних случаев. При включённых assumptions часть этих проверок исключается, если заранее известно, что среда ведёт себя более предсказуемо.


Модель оптимизаций через предположения

Оптимизации на основе assumptions строятся вокруг идеи ослабления гарантий JavaScript-спецификации в обмен на производительность. В стандартном режиме SWC обязан сохранять поведение даже в редких и исторически специфичных сценариях (например, document.all, динамические геттеры, нестандартные итераторы).

При включении предположений компилятор получает возможность:

  • убирать избыточные проверки типов и значений
  • упрощать доступ к свойствам объектов
  • оптимизировать работу с классами и spread-операторами
  • сокращать защитные обёртки вокруг встроенных конструкций

Общая структура конфигурации

В SWC assumptions задаются внутри секции jsc:

module.exports = {
  jsc: {
    assumptions: {
      // набор логических флагов
    }
  }
};

Каждый флаг описывает отдельное поведение JavaScript, которое считается истинным в целевой среде выполнения.


Оптимизация доступа к свойствам: pureGetters

pureGetters предполагает, что обращения к геттерам объектов не имеют побочных эффектов.

При включённом предположении SWC может:

  • дублировать обращения к свойствам без риска изменения состояния
  • перемещать чтения свойств для оптимизации порядка выполнения
  • устранять промежуточные переменные, связанные с безопасностью вычислений

Без этого предположения каждое обращение к getter должно рассматриваться как потенциально изменяющее состояние программы.


Классы и поля: setPublicClassFields

setPublicClassFields управляет тем, как интерпретируются публичные поля классов.

При активном предположении:

  • поля класса могут устанавливаться напрямую на экземпляр
  • дополнительная защитная логика вокруг constructor и прототипов минимизируется
  • трансформация классов становится ближе к нативной реализации современных движков

Пример влияния:

class A {
  x = 1;
}

Без оптимизации поле может быть перенесено в конструктор с дополнительной логикой проверки. С предположением — становится прямым присваиванием.


Spread-операторы: setSpreadProperties

setSpreadProperties позволяет компилятору предполагать упрощённое поведение оператора spread при работе с объектами.

В обычном режиме SWC обязан учитывать:

  • наличие символов
  • перечисляемость свойств
  • порядок копирования ключей
  • возможные геттеры

При включённом предположении:

  • копирование свойств упрощается до прямого перебора enumerable ключей
  • исключаются дополнительные проверки edge-case поведения объектов
  • ускоряется генерация кода для объектов с массовым копированием

Специфические значения Jav * aScript: noDocumentAll

noDocumentAll предполагает отсутствие поведения document.all в целевой среде.

document.all является историческим артефактом браузеров и ведёт себя нестандартно:

  • имеет тип object
  • при сравнении с null возвращает true
  • ломает строгую логику равенства

При включении предположения SWC может:

  • упрощать проверки равенства
  • устранять специальные ветвления, связанные с legacy-поведением
  • генерировать более предсказуемый код сравнения

Итерации и массивоподобные структуры: arrayLikeIsIterable

arrayLikeIsIterable предполагает, что все array-like структуры в среде поддерживают стандартный итератор.

Это позволяет SWC:

  • безопасно использовать for..of для array-like объектов
  • упрощать преобразования arguments и NodeList-подобных структур
  • устранять fallback-реализации итерации через индексы

При отсутствии предположения компилятор обязан генерировать более сложный код с проверками наличия Symbol.iterator.


Длина функций: ignoreFunctionLength

ignoreFunctionLength влияет на поведение свойства Function.length.

В JavaScript это свойство отражает количество параметров функции, но может быть изменено трансформациями (например, добавлением параметров при транспиляции async/await или rest-аргументов).

При включении предположения:

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

Это особенно важно при агрессивных преобразованиях ESNext → ES5.


Объекты и символы: поведение rest/spread

В ряде конфигураций SWC учитывает предположения о работе rest-операторов с объектами, включая исключение символов.

Хотя точное имя флага может различаться, логика сводится к следующему:

  • допускается игнорирование Symbol-ключей при деструктуризации
  • упрощается реализация object rest
  • уменьшается объём runtime-хелперов

Влияние на генерацию кода

Каждое активированное предположение уменьшает необходимость в защитных конструкциях. Это проявляется в нескольких уровнях трансформации:

  • AST-уровень: удаление условных веток и проверок
  • генерация: упрощение helper-функций
  • runtime: снижение количества вызовов вспомогательных утилит

На практике это приводит к:

  • более компактному bundle
  • ускорению выполнения кода
  • снижению количества полифиллов

Совместимость с окружениями

assumptions всегда связаны с риском нарушения совместимости. Чем больше предположений включено, тем сильнее отклонение от спецификации ECMAScript в сторону конкретной среды.

Типичные последствия:

  • ломается код, зависящий от edge-case поведения объектов
  • некорректно работают библиотеки, использующие proxy-геттеры
  • изменяется семантика редких встроенных конструкций браузеров

По этой причине предположения обычно используются только при строгом контроле целевой среды (например, modern evergreen browsers или Node.js определённой версии).


Взаимодействие с другими опциями SWC

assumptions не работают изолированно и взаимодействуют с другими уровнями конфигурации:

  • loose-режим усиливает эффект предположений
  • target определяет допустимый уровень агрессивности оптимизаций
  • minify может дополнительно упрощать уже преобразованный код

Комбинация assumptions + loose + modern target приводит к наиболее компактному результату, но снижает универсальность выходного кода.


Риски агрессивной оптимизации

Использование предположений изменяет баланс между корректностью и производительностью. Основные риски:

  • нарушение контрактов библиотек, рассчитанных на спецификацию ES
  • некорректная работа reflect- и proxy-ориентированного кода
  • расхождение поведения между dev и prod окружениями
  • сложность отладки из-за исчезновения промежуточных конструкций

Практика применения в конфигурациях

В реальных сборках assumptions обычно включаются выборочно, ориентируясь на профиль приложения. В высоконагруженных frontend-приложениях допустим более агрессивный набор флагов, тогда как библиотечный код требует минимальных предположений для сохранения универсальности.

Типичная стратегия — разделение конфигураций:

  • production bundle: расширенный набор предположений
  • library bundle: минимальный или отключённый набор
  • legacy support: отсутствие assumptions с расширенными полифиллами