Closure Compiler - это средство проверки типов и оптимизатор JavaScript. Но что могут сделать эти оптимизации, чтобы уменьшить столь важный размер пакета?
Отказ от ответственности: это не совсем честный тест. Предостережения:
- Небольшие и простые программы легче поддаются статическому анализу и их можно более агрессивно оптимизировать.
- Полифилы ES6 от Babel имеют тенденцию быть довольно тяжелыми по сравнению с Closure, которые требуют единовременных затрат и плохо выглядят в небольших примерах.
- Closure и Babel / Uglify не делают одних и тех же предположений. Оптимизация закрытия нарушает код, злоупотребляющий динамической природой JS. См. Полные ограничения. Таким образом, простые минификаторы намного проще в использовании.
- Я не эксперт по Babel / Uglify. Сообщите мне, если я использую эти инструменты неправильно или неэффективно
1. Встроенные функции
Closure Compiler будет встраивать функции, учитывая, что он может определить, что это приведет к меньшему размеру кода. Простые минификаторы, такие как Babel, не могут, потому что они не предполагают глобального анализа: нет никакого способа узнать, что кто-то не вызывает «f» вне этой программы в другом скрипте!
Закрытие: 17b Babel-minify: 34b
2. Удаление мертвого кода
Это, вероятно, самый мощный компилятор Closure для оптимизации. Однако под капотом на самом деле это серия оптимизаций. Первая проверка типа аннотирует AST информацией о типе. Затем этап компилятора, называемый «методы девиртуализации» (вы можете переключить это в пользовательском интерфейсе), превратит методы-члены в статические методы. Что-то вроде A.myMethod (x) = ›myMethod_devirtualized_ (A_instance, x). После встраивания и удаления мертвого кода у нас осталось очень мало кода!
Closure: 17b Babel-minify: 339b (полифилы ES6 здесь тяжелые)
3. Переименовать свойства прототипа.
Это кажется довольно простым, но на самом деле такую оптимизацию довольно сложно осуществить без надлежащих мер предосторожности. Опять же, это невозможно для простых минификаторов без нарушения кода для внешних вызывающих объектов и без статического анализа типов.
Closure: 56b Babel-minify: 216b (полифилы ES6 здесь тяжелые)
4. Встроенные переменные
После того, как вы закончите встраивание функций, упрощение выражений станет легким!
Закрытие 25b Babel-minify: 78b
5. Статически вывести график вызовов
Эта оптимизация возможна только при статическом анализе типов. Секретный соус здесь заключается в том, что компилятор сначала запускает проход компилятора, называемый «устранение неоднозначности методов / свойств», который, если он имеет достаточную информацию о типе соответствующего определения всех вызовов метода (), переименовывает их в A. prototype.method_belongs_toA () и B.prototype.method_belongs_toB (). Как только это будет сделано, может произойти девиртуализация метода и встраивание (см. 2).
Закрытие: 34b Babel-minify: 727b
6. Определите побочные эффекты функций для точного сокращения кода.
Анализ побочных эффектов настолько сложен, что, вероятно, потребуется отдельная запись в блоге!
Закрытие: 108b Babel-minify: 311b
7. Свернуть пространства имен объектов / статические функции.
Закрытие и конкуренты нуждаются в большом количестве полифилов для имитации этого кода ES6. Закрытие по-прежнему составляет около 1/3 размера!
Закрытие: 257b Babel-minify: 798b