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

8. Удалите неиспользованные возвраты.

Закрытие: 86b Babel-minify: 237b