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