Jak „zminimalizować” kod JavaScript


100

JQuery ma dwie wersje do pobrania, jedna to Production (19 KB, Minified i Gzipped) , a druga to Development ( 120 KB, Uncompressed Code) .

Teraz kompaktowa wersja 19kb, jeśli ją pobierzesz, zobaczysz, że nadal jest to wykonywalny kod javascript. Jak to zagęszczali? I jak mogę „zminimalizować” mój kod w ten sposób?


1
W szczególności, czy jest jakieś narzędzie online, które pozwala mi to zrobić?
KalEl

2
Natknąłem się na ten stary post z tymi samymi pytaniami, więc dobre pytanie! Kilka dobrych podstawowych informacji: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Baran51,

Odpowiedzi:


49

Minifikacja DIY

Żaden minifier nie może poprawnie skompresować złego kodu.

W tym przykładzie chcę tylko pokazać, ile robi minifier.

Co powinieneś zrobić, zanim zminimalizujesz

A jeśli chodzi o jQuery ... nie używam jQuery.jQuery jest dla starych przeglądarek, zostało stworzone ze względu na kompatybilność ... sprawdź caniuse.com, prawie wszystko działa na każdej przeglądarce (również ie10 jest teraz znormalizowane), myślę, że teraz jest tylko tutaj, aby spowolnić swoją aplikację internetową ... jeśli chcesz $(), powinieneś stworzyć własną prostą funkcję. I po co zawracać sobie głowę kompresją kodu, jeśli Twoi klienci muszą za każdym razem pobierać skrypt jquery o rozmiarze 100 kb? jak duży jest twój nieskompresowany kod? 5-6kb ..? Nie wspominając o mnóstwie wtyczek, które dodajesz, aby to ułatwić.

Oryginalny kod

Kiedy piszesz funkcję, masz pomysł, zacznij pisać, a czasami kończy się coś w rodzaju następującego kodu. Kod działa.Teraz większość ludzi przestaje myśleć i dodaje to do minifier i publikuje.

function myFunction(myNumber){
     var myArray = new Array(myNumber);
     var myObject = new Object();
     var myArray2 = new Array();
     for(var myCounter = 0 ; myCounter < myArray.length ; myCounter++){
         myArray2.push(myCounter);
         var myString = myCounter.toString()
         myObject[ myString ] = ( myCounter + 1 ).toString();
     }
    var myContainer = new Array();
    myContainer[0] = myArray2;
    myContainer[1] = myObject;
    return myContainer;
}

Oto zminimalizowany kod (dodałem nowe linie)

Zminimalizowano za pomocą ( http://javascript-minifier.com/ )

function myFunction(r){
 for(var n=new Array(r),t=new Object,e=new Array,a=0;a<n.length;a++){
  e.push(a);
  var o=a.toString();
  t[o]=(a+1).toString()
 }
 var i=new Array;
 return i[0]=e,i[1]=t,i
}

Ale czy te wszystkie zmienne, jeśli, pętle i definicje są konieczne?

Przez większość czasu NIE !

  1. Usuń niepotrzebne if, loop, var
  2. Zachowaj kopię swojego oryginalnego kodu
  3. Użyj minifier

OPCJONALNIE (zwiększa wydajność i krótszy kod)

  1. używaj operatorów skrótów
  2. użyj operatorów bitowych (nie używaj Math)
  3. użyj a, b, c ... dla twoich zmiennych temp
  4. użyj starej składni ( while, for... nie forEach)
  5. użyj argumentów funkcji jako symbolu zastępczego (w niektórych przypadkach)
  6. usuń niepotrzebne "{}","()",";",spaces,newlines
  7. Użyj minifier

Jeśli minifier może skompresować kod, robisz to źle.

Żaden minifier nie może poprawnie skompresować złego kodu.

majsterkowanie

function myFunction(a,b,c){
 for(b=[],c={};a--;)b[a]=a,c[a]=a+1+'';
 return[b,c]
}

Robi dokładnie to samo, co powyższe kody.

Występ

http://jsperf.com/diyminify

Zawsze musisz pomyśleć, czego potrzebujesz:

Zanim powiesz „Nikt nie napisałby kodu takiego jak ten poniżej”, przejdź tutaj i sprawdź pierwsze 10 pytań ...

Oto kilka typowych przykładów, które widzę co dziesięć minut.

Chcesz mieć stan wielokrotnego użytku

if(condition=='true'){
 var isTrue=true;
}else{
 var isTrue=false;
}
//same as
var isTrue=!!condition

Alert tak, tylko jeśli istnieje

if(condition==true){
 var isTrue=true;
}else{
 var isTrue=false;
}
if(isTrue){
 alert('yes');
}
//same as
!condition||alert('yes')
//if the condition is not true alert yes

Alert tak lub nie

if(condition==true){
 var isTrue=true;
}else{
 var isTrue=false;
}
if(isTrue){
 alert('yes');
}else{
 alert('no');
}
//same as
alert(condition?'yes':'no')
//if the condition is true alert yes else no

Zamień liczbę na ciąg lub odwrotnie

var a=10;
var b=a.toString();
var c=parseFloat(b)
//same as
var a=10,b,c;
b=a+'';
c=b*1

//shorter
var a=10;
a+='';//String
a*=1;//Number

Zaokrąglij liczbę

var a=10.3899845
var b=Math.round(a);
//same as
var b=(a+.5)|0;//numbers up to 10 decimal digits (32bit)

Piętro numer

var a=10.3899845
var b=Math.floor(a);
//same as
var b=a|0;//numbers up to 10 decimal digits (32bit)

Sprawa przełącznik

switch(n)
{
case 1:
  alert('1');
  break;
case 2:
  alert('2');
  break;
default:
  alert('3');
}

//same as
var a=[1,2];
alert(a[n-1]||3);

//same as
var a={'1':1,'2':2};
alert(a[n]||3);

//shorter
alert([1,2][n-1]||3);
//or
alert([1,2][--n]||3);

próbuj złapać

if(a&&a[b]&&a[b][c]&&a[b][c][d]&&a[b][c][d][e]){
 console.log(a[b][c][d][e]);
}

//this is probably the onle time you should use try catch
var x;
try{x=a.b.c.d.e}catch(e){}
!x||conole.log(x);

więcej, jeśli

if(a==1||a==3||a==5||a==8||a==9){
 console.log('yes')
}else{
 console.log('no');
}

console.log([1,3,5,8,9].indexOf(a)!=-1?'yes':'no');

ale indexOfwolno czytać to https://stackoverflow.com/a/30335438/2450730

liczby

1000000000000
//same as
1e12

var oneDayInMS=1000*60*60*24;
//same as
var oneDayInMS=864e5;

var a=10;
a=1+a;
a=a*2;
//same as
a=++a*2;

Kilka fajnych artykułów / stron, które znalazłem na temat bitwise / shorthand:

http://mudcu.be/journal/2011/11/bitwise-gems-and-other-optimizations/

http://www.140byt.es/

http://www.jquery4u.com/javascript/shorthand-javascript-techniques/

Istnieje również wiele witryn jsperf pokazujących wydajność shorthand & bitwsie, jeśli szukasz przy użyciu swojej ulubionej wyszukiwarki.

Mógłbym chodzić godzinami ... ale myślę, że na razie wystarczy.

jeśli masz jakieś pytania, po prostu zadaj.

I pamiętaj

Żaden minifier nie może poprawnie skompresować złego kodu.


30
Nie ma prawie żadnego powodu, aby ręcznie zmniejszać kod. Napisz kod, który będzie łatwo zrozumiały dla innych programistów (lub Ciebie, 10 miesięcy później). Tak, prostsze znaczy lepsze. Użyj zminimalizowanego w zautomatyzowanym procesie kompilacji, który zachowuje oryginał. W prawie każdym przypadku wszelkie zyski szybkości wynikające z ręcznej optymalizacji są daleko, znacznie większe od kosztów, jakie deweloperzy odszyfrowują zminimalizowany kod.
alttag

4
zależy od tego, co robisz. jeśli pracujesz na przykład z animacjami / kanwami, ogromnymi zbiorami danych i manipulacją plikami, szybki kod jest bardzo ważny, szczególnie na urządzeniach mobilnych ... chodzi o to, że dla niektórych programistów jest trudny do odczytania. tak ... piszę kod, ponieważ Pentium 2 .. więc prawdopodobnie 1998, mogę odczytać kod iz mojego doświadczenia mam mniej kodu do sprawdzenia błędów. A co do prędkości .. mh, twój błąd. Wydajność wzrasta przy użyciu bitwise / i skrótów w złożonych funkcjach jest szalona. Szczególnie testowanie na różnych urządzeniach / przeglądarkach. Użyj google skróconego i bitowego javascript i znajdziesz wiele przykładów
Cocco

Oto przykład zaokrąglenia: (10.4899845 +.5)|0
Oto

Kod DIY został właśnie dodany do mojego „nadmiernie zoptymalizowanego” pliku. NIE robi dokładnie tego, co robi oryginalny kod, gdy podano wartość mniejszą od zera (myNumber lub a). Oryginalny kod zgłasza wyjątek, a „ulepszony” kod przechodzi w nieskończoną pętlę.
Donald Rich,

To brzmi jak taka zła rada z punktu widzenia możliwości
wsparcia


10

Google właśnie udostępnił kompilator javascript, który może zminimalizować twój kod, wyeliminować martwe gałęzie kodu i więcej optymalizacji.

kompilator google javascript

Pozdrawiam
K.


3

Wraz z minifikacją możesz również zakodować base64. To sprawia, że ​​plik jest znacznie bardziej skompresowany. Jestem pewien, że widziałeś pliki js, które są opakowane w funkcję eval () z przekazanymi parametrami (p, a, c, k, e, r). Przeczytałem w tym artykule Jak zminimalizować plik JavaScript?


kodowanie base64 nie kompresuje twojego kodu, robi dokładnie odwrotnie, otrzymujesz więcej znaków. Możesz skompresować swój ciąg LZH, ktoś stworzył skrypt JS na githubie, który wykonuje kompresję LZH na łańcuchach nazwanych: lz-string, możesz go użyć do skompresowania swojego kodu: pieroxy.net/blog/pages/lz-string/index.html
beliha

3

Napisałem mały skrypt, który wywołuje interfejs API w celu zminimalizowania skryptu, sprawdź to:

#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use Fcntl;

my %api = ( css => 'https://cssminifier.com/raw', js => 'https://javascript-minifier.com/raw' );

my $DEBUG = 0;

my @files = @ARGV;

unless ( scalar(@files) ) {
    die("Filename(s) not specified");
}

my $ua = LWP::UserAgent->new;

foreach my $file (@files) {
    unless ( -f $file ) {
        warn "Ooops!! $file not found...skipping";
        next;
    }

    my ($extn) = $file =~ /\.([a-z]+)/;

    unless ( defined($extn) && exists( $api{$extn} ) ) {
        warn "type not supported...$file...skipping...";
        next;
    }

    warn "Extn: $extn, API: " . $api{$extn};

    my $data;

    sysopen( my $fh, $file, O_RDONLY );
    sysread( $fh, $data, -s $file );
    close($fh);

    my $output_filename;

    if ( $file =~ /^([^\/]+)\.([a-z]+)$/ ) {
        $output_filename = "$1.min.$2";
    }

    my $resp = $ua->post( $api{$extn}, { input => $data } );

    if ( $resp->is_success ) {
        my $resp_data = $resp->content;
        print $resp_data if ($DEBUG);
        print "\nOutput: $output_filename";

        sysopen( my $fh, $output_filename, O_CREAT | O_WRONLY | O_TRUNC );
        if ( my $sz_wr = syswrite( $fh, $resp_data ) ) {
            print "\nOuput written $sz_wr bytes\n";
            my $sz_org = -s $file;

            printf( "Size reduction %.02f%%\n\n", ( ( $sz_org - $sz_wr ) / $sz_org ) * 100 );
        }   
        close($fh);
    }
    else {
      warn: "Error: $file : " . $resp->status_line;
    }
}

Stosowanie:

./minifier.pl a.js c.css b.js cc.css t.js j.js [..]

1

Niedawno musiałem wykonać to samo zadanie. Podczas gdy kompresory wymienione w JavaScript CompressorRater wykonują świetną robotę, a narzędzie jest bardzo przydatne, kompresory nie działały dobrze z niektórymi kodami jQuery, których używam (kontrole $ .getScript i jQuery.fn). Nawet Google Closure Compressor zakrztusił się na tych samych liniach. Chociaż mogłem w końcu pozbyć się załamań, ciągłe mrużenie oczu było daleko za dużo.

Tym, który w końcu zadziałał bez problemu, był UglifyJS (dzięki @ Aries51 ), a kompresja była tylko nieznacznie mniejsza niż wszystkie inne. I podobnie jak Google ma interfejs API HTTP. Packer jest również fajny i ma implementację językową w Perlu, PHP i .NET.


1

Obecnie istnieją dwa sposoby zmniejszania kodu:

  1. stosujesz minifier po stronie zaplecza aplikacji - tutaj zaletą jest to, że możesz zastosować wersjonowanie i masz większą kontrolę nad swoim kodem - możesz praktycznie w pełni zautomatyzować proces minifikacji, a najlepszą praktyką byłoby zastosowanie go przed utworzeniem kodu przesłane na serwer - najlepiej użyć tego, gdy masz dużo frontendu (do zminimalizowania) JavaScript i kodu CSS:

http://yui.github.io/yuicompressor/

Wiele takich narzędzi jest dostępnych również dla Node i npm - dobrą praktyką jest automatyzacja obsługi JavaScript za pomocą Grunt.

  1. możesz użyć niektórych istniejących bezpłatnych narzędzi do minifikacji, które działają w trybie online - praktycznie pozwalają one zrobić to samo, ale ręcznie. Radziłbym używać ich, gdy ilość twojego kodu javascript / css jest mniejsza - niewiele plików

http://www.modify-anything.com/



0

Jeśli używasz edytora VSCode, dostępnych jest wiele wtyczek / rozszerzeń.

Na MinifyAllprzykład jest bardzo dobry - kompatybilny z wieloma rozszerzeniami.

Zainstaluj go i ponownie załaduj VSCode. Następnie kliknij plik, otwórz paletę poleceń ( Ctrl+Shift+p), wpisz minify ten dokument ( Ctrl+alt+m) inne dostępne opcje, takie jak zachowaj oryginalny dokument i tak dalej! Łatwo!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.