2013-03-17 15 views
19

Natknąłem się na kod this performance report skompresowany przy użyciu różnych minifier i obfuscatorów. Zaskakujące jest to, że oprócz trybu zaawansowanego Zamknięcia, w większości przypadków wszystkie inne minifiery kodują wynik, który działa gorzej niż kod nieskompresowany. Jak to wyjaśnić?Dlaczego zminimalizowany lub zaciemniony JavaScript działa gorzej niż nieskompresowany kod?

Przewiń w dół do końca page, aby wyświetlić raport. Oto zrzuty ekranu:

enter image description here enter image description here enter image description here enter image description here

Legenda:

  • Blue - YUI Compressor
  • Red - Zamknięcie (tryb zaawansowany)
  • Orange - Zamknięcie (tryb podstawowy)
  • Zielona - JS Min
  • Purple - JS Packer
  • Light Blue - UglifyJS
  • Pink - kod nieskompresowany
+0

możliwy duplikat [Czy osiągnięto wydajność podczas uruchamiania zaciemnionego kodu?] (Http://stackoverflow.com/questions/2646216/is-there-a-performance-hit-when-running-obfuscated-code) – Barmar

+8

To nie jest duplikat @Barmara - tak, chodzi o zaciemnianie, ale mówi o Javie i C#, a nie o JavaScript. – nnnnnn

+0

Dlaczego konieczne jest porównanie zaciemniania z wydajnością? Jeśli ktoś odczuwa potrzebę zaciemnienia kodu, nie sądzę, aby wydajność była kwestią. – Ozzy

Odpowiedz

7

Najpierw pozwól mi zagrać w adwokata diabła: Kod tak naprawdę "nie wykonuje" niczego (nic poważnego, co znaczy, poza JS Packerem). Jest to zasadniczo definicja funkcji, obiektów i właściwości.

JS Packer nie generuje kodu JavaScript, lecz skompresowany tekst, który należy rozpakować w środowisku wykonawczym. Dlatego jest znacznie wolniej. Zamknięcie Google przy użyciu zaawansowanej optymalizacji zastępuje identyfikatory, gdy tylko jest to możliwe. Tak więc przy analizowaniu skryptu musi już być przewaga wydajności.

Powiedział, że można poświęcić wydajność dla rozmiaru kodu. Jednym z przykładów jest zastąpienie true i false z !0 i !1. Zależy jednak od silnika JavaScript. To może być zoptymalizowane przez silnik przed pierwszym wywołaniem, po to, po kilku rozmów, nigdy ... kto wie;)

Nowe ustalenia

Zrobiłem kilka profili w międzyczasie i uświadomiłem sobie, że Zapomniałem jednej rzeczy: zbierania śmieci. Wpływ może być wystarczający, aby wyjaśnić niektóre różnice między skryptami i przeglądarkami (różne silniki!).

Połączyć to z faktem, że kod nie robi dużo i coś masz. W jednym teście miałem czas procesora na zbieranie śmieci około 3% dla nieskompresowanego i 9% (!) Dla JSMin. Co oznacza zupełnie inne wyniki dla prawie równego kodu.

Nawet nowsze odkrycia

Po uruchomieniu JSMin pierwszy to szybciej niż bez kompresji. Próbowałem tego kilka razy i zawsze miałem taki sam wynik. Potwierdza to poprzednie ustalenia. Jestem teraz dość pewny, że znaleźliśmy rozwiązanie.

+2

+1 dla kodu, który nic nie robi. Jedyne testy, które mają znaczenie, są twoimi własnymi. –

+0

Oczywiście kod nie "wykonuje" niczego. Więc nie jest to reprezentant dobrego benchmarku. Dlaczego jednak miniony kod działa gorzej * dla tego konkretnego testu *? JSMin, w szczególności, [po prostu pomija niektóre białe znaki] (http://www.crockford.com/javascript/jsmin.html). Dlaczego więc miałoby gorzej działać? –

+0

Istnieją nawet wyniki, w których wydajność JSMin jest równa wersji nieskompresowanej. Ale wykonanie JSMin też wydaje mi się dziwne. Poza tym musimy wziąć pod uwagę 3 kwestie: 1. Analiza: budowanie AST bierze swój udział w czasie, w szczególności dla tego skryptu. 2.Wszystko zależy od silnika JavaScript. Wyniki różnią się znacznie. 3. Same ramy lub sposób ich wykonywania ** może ** mieć wpływ ** w tym ** przypadku. Nie sądzę, ale nie mogę powiedzieć na pewno. – zeroflagL

-1

Tak, zaciemniania może powodować pewne problemy z wydajnością, ale nie jest prawdą, że kod minified wykonać gorzej niż nieskompresowanego. W rzeczywistości miniony kod działa lepiej niż nieskompresowany. Dzieje się tak, ponieważ minilowany kod ma znacznie krótszą nazwę zmiennej/funkcji, dzięki czemu wywołanie referencyjne do przydzielonej przestrzeni pamięci jest znacznie łatwiejsze!

-1

Wygląda na to, że nieumyślnie pomyliłeś zminimalizowanie z zaciemnianiem.

Aby zrozumieć te dwie technologie, wyjaśnię je osobno.

Minikompresja to proces, w którym rozmiar pliku źródłowego zostaje zmniejszony i przekształcony w format przeznaczony do bardziej wydajnej czytelności maszyn. Odbywa się to poprzez (a) usunięcie komentarzy i niepotrzebnych spacji oraz ewentualnie (b) zastąpienie nazw zmiennych prostymi, przyrostowymi nazwami zmiennych, często rozpoczynającymi się od jednego znaku. Wynikowy kod nadal działa tak samo, jak oryginalny kod, ale teoretycznie jest szybszy, gdy przeglądarka analizuje i kompiluje.

Obfuskacja to technika polegająca na tym, że kod jest modyfikowany w taki sposób, że nie jest już rozpoznawalny jako oryginalny kod źródłowy i często jest wykorzystywany do zniechęcania do odwrotnej inżynierii kodu zastrzeżonego. Niektóre zmiany mogą mieć na nie wpływ, na przykład kod może zostać zaszyfrowany, a następnie odszyfrowany ponownie w czasie wykonywania. To powiedziawszy, typowe dla obfuscatora kodu jest również kończenie pracy przez minimalizowanie danych wyjściowych.

Można uważać, że minifikacja jest prymitywną formą zaciemniania, ale zwykle takie procesy są przeprowadzane bardziej dla wydajności i/lub celów przepustowości.

Powiązane problemy