Ограничения минификации в esbuild по сравнению с Terser

Минификация в JavaScript выполняется разными классами инструментов, и различия между ними определяются не только качеством результата, но и философией проектирования. esbuild ориентирован на максимальную скорость обработки кода и интеграцию сборки в единый пайплайн. Terser делает акцент на глубокой оптимизации AST и максимально агрессивной трансформации кода.

Эти различия напрямую формируют набор ограничений, которые проявляются при минификации в esbuild по сравнению с Terser.


Уровень анализа AST и глубина преобразований

Terser работает с детализированным AST и выполняет многоступенчатую трансформацию дерева:

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

esbuild использует более упрощённую модель AST и сознательно ограничивает глубину анализа, чтобы обеспечить скорость работы.

Ограничение esbuild:

  • менее точный анализ побочных эффектов
  • более консервативное удаление кода
  • упрощённые правила преобразования выражений

Это приводит к тому, что некоторые оптимизации в Terser просто недоступны в esbuild.


Контроль над mangling-ом идентификаторов

Terser предоставляет детализированное управление переименованием:

  • отдельные настройки для top-level и локальных переменных
  • возможность исключения имён из mangling
  • тонкая настройка reserved identifiers
  • контроль над классами, свойствами и функциями

esbuild использует более простую стратегию:

  • глобальный и локальный mangling без глубоких настроек
  • отсутствие тонкой сегментации правил переименования
  • минимальный набор опций управления именами

Практическое ограничение: в esbuild невозможно добиться того же уровня контроля над именами, который доступен в Terser, особенно в больших кодовых базах с частично экспортируемыми API.


Оптимизация условий и логических выражений

Terser способен выполнять сложные преобразования:

  • упрощение вложенных тернарных операторов
  • преобразование логических цепочек в более короткие формы
  • свёртка условий с побочными эффектами
  • агрессивное удаление unreachable-кода

esbuild ограничивает такие преобразования:

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

Удаление мёртвого кода (DCE)

Dead Code Elimination в Terser:

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

esbuild выполняет DCE более поверхностно:

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

Следствие: в некоторых проектах итоговый размер бандла после Terser оказывается заметно меньше, чем после esbuild, особенно при наличии сложной условной логики.


Инлайнинг функций и констант

Terser поддерживает:

  • агрессивный inline small functions
  • подстановку константных выражений
  • оптимизацию цепочек вызовов
  • разворачивание простых вычислений

esbuild реализует инлайнинг значительно осторожнее:

  • ограниченный inline только простых выражений
  • минимальная константная свёртка
  • отказ от сложных преобразований функций

Это снижает риск изменения поведения кода, но уменьшает потенциальную степень сжатия.


Работа с побочными эффектами

Terser активно анализирует:

  • чистоту функций
  • возможные side effects выражений
  • безопасное удаление вызовов
  • переупорядочивание некоторых операций

esbuild придерживается более строгой модели:

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

Ограничение: это приводит к сохранению кода, который Terser мог бы удалить.


Оптимизация свойств объектов

Terser способен:

  • удалять неиспользуемые свойства объектов
  • преобразовывать структуры объектов в более компактные формы
  • выполнять глубокий анализ доступности свойств

esbuild ограничен:

  • удаление свойств происходит только в очевидных случаях
  • отсутствует глубокая реконструкция объектов
  • нет сложной трансформации структуры данных

Поддержка экспериментальных и редких JavaScript-конструкций

Terser регулярно расширяет поддержку сложных паттернов:

  • нестандартные синтаксические конструкции
  • сложные цепочки выражений
  • редкие случаи использования eval и with (с ограничениями)

esbuild предпочитает:

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

Поведение при сложных модулях

Terser способен выполнять более глубокую работу с модульной структурой:

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

esbuild фокусируется на:

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

Баланс скорости и глубины оптимизации

esbuild делает ключевой выбор в пользу производительности:

  • сверхбыстрая минификация
  • низкое потребление ресурсов
  • предсказуемое поведение

Terser выбирает:

  • более медленную обработку
  • максимальную глубину анализа
  • агрессивную оптимизацию результата

Следствие: ограничения esbuild являются прямым следствием архитектурного приоритета скорости над полнотой оптимизаций.


Практические последствия в реальных проектах

Разница между подходами проявляется в типичных сценариях:

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

Разница в размере итогового бандла может быть незначительной в простых проектах и существенно возрастать в сложных архитектурах с большим количеством условной логики и переиспользуемых функций.