Почему минимизированный или обфусцированный JavaScript работает хуже, чем несжатый код?

Я наткнулся на этот отчет о производительности кода JavaScript, сжатого с помощью различных минификаторов и обфускаторов. . Удивительно то, что кроме расширенного режима Closure, в большинстве случаев все остальные минификаторы выдают код, который работает хуже, чем несжатый код. Как это объяснить?

Прокрутите вниз до конца страницы, чтобы просмотреть отчет. Вот скриншоты:

введите здесь описание изображениявведите здесь описание изображения введите здесь описание изображениявведите здесь описание изображения

Легенда:

  • Синий - Компрессор YUI
  • Красный — закрытие (расширенный режим)
  • Оранжевый — Закрытие (базовый режим)
  • Зеленый — JS мин.
  • Фиолетовый — упаковщик JS
  • Голубой — UglifyJS
  • Розовый — несжатый код

person Dheeraj Vepakomma    schedule 17.03.2013    source источник
comment
На самом деле это не дубликат @Barmar - да, речь идет об обфускации, но речь идет о Java и C #, а не о JavaScript.   -  person nnnnnn    schedule 17.03.2013
comment
Почему необходимо сравнивать обфускацию с производительностью? Если кто-то чувствует необходимость запутать свой код, я не думаю, что производительность будет проблемой.   -  person Ozzy    schedule 17.03.2013
comment
Я не уверен, что операции в секунду - это действительно отличная метрика... Конечно, это просто показывает, какой обфускатор предпочитает самые простые операции, и ничего не говорит о скорости кода в целом...   -  person David McMullin    schedule 17.03.2013
comment
@Ozzy, запутывание / сжатие в JS больше связано с уменьшением объема данных, которые необходимо отправить в браузер. Это ускорит загрузку страницы, и, конечно же, вы будете заинтересованы в том, чтобы она работала быстрее.   -  person David McMullin    schedule 17.03.2013
comment
@Ozzy Это не тот или иной вопрос, и то, и другое даст наименьший размер файла и самое быстрое время загрузки.   -  person David McMullin    schedule 17.03.2013
comment
Если компрессор упаковывает код таким образом, что сначала он должен распаковать себя, то, очевидно, это связано с накладными расходами. Кроме того, например, компрессоры могут заменять повторяющиеся имена функций строками (a = 'getElementById'; document[a]();), которые, вероятно, имеют очень разные характеристики производительности.   -  person deceze♦    schedule 17.03.2013


Ответы (3)


Сначала позвольте мне сыграть в адвоката дьявола: код на самом деле ничего не «выполняет» (ничего серьезного, я имею в виду, кроме JS Packer). По сути, это определение функций, объектов и свойств.

JS Packer создает не код JavaScript, а сжатый текст, который необходимо распаковать во время выполнения. Вот почему это намного медленнее. Google Closure с помощью Advanced Optimization заменяет идентификаторы, когда это возможно. Таким образом, при разборе сценария уже должно быть преимущество в производительности.

Тем не менее, можно пожертвовать производительностью ради размера кода. Одним из примеров является замена true и false на !0 и !1. Хотя это зависит от движка JavaScript. Могло быть оптимизировано движком до первого вызова, после него, после нескольких вызовов, никогда... кто знает ;)

Новые результаты

Тем временем я профилировал и понял, что забыл одну вещь: сборку мусора. Этого влияния может быть достаточно, чтобы объяснить некоторые различия между скриптами и браузерами (разные движки!).

Объедините это с тем фактом, что код мало что делает, и у вас есть что-то. В одном тесте у меня было процессорное время для сборки мусора около 3% для несжатого и 9%(!) для JSMin. Это означает совершенно разные результаты для почти одинакового кода.

Еще новые результаты

Когда вы сначала запускаете JSMin, он быстрее, чем несжатый. Я пробовал это несколько раз и всегда получал один и тот же результат. Это подтверждает предыдущие выводы. Теперь я уверен, что мы нашли решение.

person a better oliver    schedule 17.03.2013
comment
+1 за код ничего не делает. Единственные ориентиры, которые имеют значение, — это ваши собственные. - person David McMullin; 17.03.2013
comment
Конечно, код действительно ничего не выполняет. Так что это не показатель хорошего эталона. Тем не менее, почему минимизированный код работает хуже для этого конкретного теста? JSMin, в частности, просто опускает некоторые пробелы. Так почему же он должен работать хуже? - person Dheeraj Vepakomma; 17.03.2013
comment
Есть даже результаты, в которых производительность JSMin равна производительности несжатой версии. Но производительность JSMin мне тоже кажется странной. Кроме того, мы должны рассмотреть 3 вопроса: 1. Разбор: сборка AST занимает свою долю времени, в частности, для этого скрипта. 2. Все зависит от движка JavaScript. Результаты сильно различаются. 3. Сама структура или то, как она выполняет тесты, могут иметь влияние в этом случае. Не думаю, но точно сказать не могу. - person a better oliver; 17.03.2013
comment
Боюсь, чтобы объяснить каждую разницу, потребовалось бы участие поставщиков браузеров. Или проверить исходный код JS Engines;) - person a better oliver; 17.03.2013

Кажется, вы могли непреднамеренно перепутать минимизацию с запутыванием.

Чтобы понять две технологии, я объясню их отдельно.

Минификация — это процесс, при котором размер исходного файла уменьшается и преобразуется в формат, предназначенный для более эффективной машиночитаемости. Это делается путем (а) удаления комментариев и ненужных пробелов и, возможно, (б) замены имен переменных простыми инкрементными именами переменных, часто начинающимися с одного символа. Полученный код по-прежнему функционирует так же, как исходный код, но теоретически браузер быстрее анализирует и компилирует его.

Обфускация — это метод, при котором код модифицируется таким образом, что он больше не распознается как оригинальный исходный код, и часто используется для предотвращения реинжиниринга проприетарного кода. Некоторые изменения могут иметь накладные расходы, например, код может быть зашифрован, а затем снова расшифрован во время выполнения. Тем не менее, для обфускатора кода характерно также завершать работу, минимизируя вывод.

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

person William    schedule 12.12.2015

Да, обфускация может вызвать некоторые проблемы с производительностью, но это не правда, что минимизированный код работает хуже, чем несжатый. На самом деле минимизированный код работает лучше, чем несжатый. Это связано с тем, что минифицированный код имеет гораздо более короткое имя переменной/функции, что значительно упрощает обращение к выделенному пространству памяти!

person spaceman12    schedule 17.03.2013