Come "minimizzare" il codice Javascript


99

JQuery ha due versioni per il download, una è Production (19KB, Minified e Gzipped) e l'altra è Development (120KB, Uncompressed Code) .

Ora la versione compatta da 19kb, se la scarichi, vedrai che è ancora un codice eseguibile javascript. Come l'hanno compattato? E come posso "minimizzare" anche il mio codice in questo modo?


1
In particolare, esiste un'utilità online che mi consenta di farlo?
KalEl

2
Mi sono imbattuto in questo vecchio post con le stesse domande, quindi bella domanda! Alcune buone informazioni di base: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Aries51

Risposte:


48

Minificazione fai da te

Nessun minifier può comprimere correttamente un codice errato.

In questo esempio voglio solo mostrare quanto fa un minifier.

Cosa dovresti fare prima di minimizzare

E per quanto riguarda jQuery ... non uso jQuery.jQuery è per i vecchi browser, è stato creato per motivi di compatibilità .. controlla caniuse.com, quasi tutto funziona su tutti i browser (anche ie10 è standardizzato ora), penso che ora lo sia solo qui per rallentare la tua applicazione web ... se ti piace $()dovresti creare la tua semplice funzione E perché preoccuparsi di comprimere il tuo codice se i tuoi clienti hanno bisogno di scaricare lo script jquery da 100kb ogni volta? quanto è grande il tuo codice non compresso? 5-6kb ..? Per non parlare delle tonnellate di plugin a cui aggiungi per renderlo più facile.

Codice originale

Quando scrivi una funzione hai un'idea, inizia a scrivere cose ea volte ti ritrovi con qualcosa di simile al seguente codice. Il codice funziona. Ora la maggior parte delle persone smette di pensare e aggiunge questo a un minifier e lo pubblica.

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;
}

Ecco il codice minimizzato (ho aggiunto le nuove righe)

Minificato utilizzando ( 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
}

Ma sono necessarie tutte quelle variabili, se, loop e definizioni?

La maggior parte delle volte NO !

  1. Rimuovi if, loop, var non necessari
  2. Conserva una copia del codice originale
  3. Usa il minifier

OPZIONALE (aumenta le prestazioni e abbrevia il codice)

  1. utilizzare operatori stenografici
  2. usa operatori bit per bit (non usare Math)
  3. usa a, b, c ... per i tuoi variabili temporanei
  4. usa la vecchia sintassi ( while, for... non forEach)
  5. usa gli argomenti della funzione come segnaposto (in alcuni casi)
  6. rimuovere inutilmente "{}","()",";",spaces,newlines
  7. Usa il minifier

Ora, se un minifier può comprimere il codice, lo stai facendo male.

Nessun minifier può comprimere correttamente un codice errato.

Fai da te

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

Fa esattamente la stessa cosa dei codici sopra.

Prestazione

http://jsperf.com/diyminify

Devi sempre pensare a cosa ti serve:

Prima di dire "Nessuno scriverebbe un codice come quello qui sotto", controlla le prime 10 domande qui ...

Ecco alcuni esempi comuni che vedo ogni dieci minuti.

Desidera una condizione riutilizzabile

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

Avviso sì solo se esiste

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

Avviso sì o no

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

Converti un numero in una stringa o viceversa

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

Arrotonda un numero

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

Piano un numero

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

scatola dell'interruttore

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);

prova a prendere

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);

di più se

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');

ma indexOfè lento leggere questo https://stackoverflow.com/a/30335438/2450730

numeri

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;

Alcuni bei articoli / siti che ho trovato su bit a bit / stenografia:

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

http://www.140byt.es/

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

Ci sono anche molti siti jsperf che mostrano le prestazioni di stenografia e bitwsie se cerchi con il tuo motore di ricerca preferito.

Potrei farne uno per ore .. ma penso sia abbastanza per ora.

se hai qualche domanda basta chiedere.

E ricorda

Nessun minifier può comprimere correttamente un codice errato.


30
Non c'è quasi alcun motivo per minimizzare manualmente il codice. Scrivi codice facilmente comprensibile da altri sviluppatori (o da te, 10 mesi dopo). Sì, più semplice è meglio. Usa un minificato in un processo di costruzione automatizzato che preserva l'originale. In quasi tutti i casi, qualsiasi guadagno di velocità dall'ottimizzazione manuale è di gran lunga superato dal costo degli sviluppatori che decifrano il codice minificato.
alttag

4
dipende da cosa stai facendo. se lavori con animazioni / canvas, enormi set di dati e manipolazione di file, ad esempio, un codice veloce è molto importante, specialmente sui dispositivi mobili ... il punto è che per alcuni sviluppatori è difficile da leggere. sì ... scrivo codice da allora il pentium 2 .. quindi probabilmente nel 1998, posso leggere il codice e nella mia esperienza ho meno codice per controllare gli errori. E riguardo alla velocità .. mh, ti sbagli. L'aumento delle prestazioni utilizzando bit a bit / e stenografia in funzioni complesse è folle.specialmente testare su vari dispositivi / browser.usare google shorthandbitwise javascript e trovi molti esempi
cocco

Re il tuo esempio di arrotondamento: (10.4899845 +.5)|0risultati in 10 invece di 11.
DanMan

Il codice DIY è stato appena aggiunto al mio file "ottimizzato". NON fa esattamente ciò che fa il codice originale quando viene fornito un valore inferiore a zero (myNumber o a). Il codice originale genera un'eccezione e il codice "migliorato" entra in un ciclo infinito.
Donald Rich,

Sembra un pessimo consiglio dal punto di vista della supportabilità
donkz


10

Google ha appena reso disponibile un compilatore javascript in grado di minimizzare il codice, eliminare rami di codice morto e ulteriori ottimizzazioni.

compilatore javascript google

Saluti
K


3

Oltre a minimizzare puoi anche codificarlo in base64. Rende il tuo file molto più compresso. Sono sicuro che hai visto file js racchiusi in una funzione eval () con parametri (p, a, c, k, e, r) passati. L'ho letto in questo articolo Come minimizzare un file Javascript?


La codifica base64 non comprime il codice, fa esattamente l'opposto, ti ritroverai con più caratteri. Puoi comprimere LZH la tua stringa, qualcuno ha creato uno script JS su github che esegue la compressione LZH su stringhe denominate: lz-string, puoi usarlo per comprimere il tuo codice: pieroxy.net/blog/pages/lz-string/index.html
beliha

3

Ho scritto un minuscolo script che chiama un'API per minimizzare il tuo script, dai un'occhiata:

#!/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;
    }
}

Utilizzo:

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

1

Recentemente ho dovuto eseguire la stessa operazione. Mentre i compressori elencati in The JavaScript CompressorRater fanno un ottimo lavoro e lo strumento è molto utile, i compressori non funzionavano bene con un po 'di codice jQuery che sto usando ($ .getScript e controlli jQuery.fn). Anche il Google Closure Compressor si è soffocato sulle stesse linee. Anche se alla fine avrei potuto appianare i nodi, era tutt'altro che strabico da fare costantemente.

Quello che alla fine ha funzionato senza problemi è stato UglifyJS (grazie @ Aries51 ) e la compressione era solo leggermente inferiore a tutte le altre. E simile a Google ha un'API HTTP. Packer è anche carino e ha l'implementazione del linguaggio in Perl, PHP e .NET.


1

Attualmente ci sono 2 modi per minimizzare il tuo codice:

  1. applichi i minificatori sul lato back-end della tua applicazione - qui il vantaggio è che puoi applicare il controllo delle versioni e hai più controllo del tuo codice - puoi praticamente automatizzare completamente il processo di minificazione e la migliore pratica sarebbe applicarlo prima che il tuo codice sia caricato sul server: è meglio utilizzarlo quando hai molto codice Javascript e CSS di frontend (da minimizzare):

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

Molti di questi strumenti sono disponibili anche per Node e npm: è buona norma automatizzare la mnificazione di Javascript con Grunt.

  1. puoi utilizzare alcuni degli strumenti gratuiti esistenti per la minificazione che sono in esecuzione online - questi praticamente ti permettono di fare lo stesso, ma manualmente. Ti consiglio di usarli quando la quantità del tuo codice javascript / css è inferiore - non molti file

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.