Como 'reduzir' o código Javascript

99

O JQuery tem duas versões para download, uma é Produção (19KB, Minificado e Gzipado) e a outra é Desenvolvimento (120KB, Código Descomprimido) .

Agora a versão compacta de 19kb, se você baixá-la, verá que ainda é um código executável javascript. Como eles compactaram isso? E como posso 'reduzir' meu código assim também?

KalEl
fonte
1
Especialmente, existe algum utilitário online que me permite fazer isso?
KalEl
2
Me deparei com este post antigo com as mesmas perguntas, então boa pergunta! Algumas boas informações básicas: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Áries51

Respostas:

48

Minificação DIY

Nenhum minificador pode compactar corretamente um código incorreto.

Neste exemplo, eu só quero mostrar o quanto um minificador faz.

O que você deve fazer antes de minimizar

E em relação ao jQuery ... eu não uso jQuery.jQuery é para navegadores antigos, foi feito por razões de compatibilidade .. verifique caniuse.com, quase tudo funciona em todos os navegadores (também o ie10 é padronizado agora), acho que agora é apenas aqui para desacelerar seu aplicativo da web ... se você gosta, $()você deve criar sua própria função simples. E por que se preocupar em compactar seu código se seus clientes precisam baixar o script jquery de 100kb toda vez? Qual é o tamanho do seu código descompactado? 5-6kb ..? Sem falar nas toneladas de plug-ins que você adiciona para facilitar.

Código Original

Quando você escreve uma função, você tem uma ideia, começa a escrever coisas e às vezes acaba com algo como o código a seguir. O código funciona. Agora a maioria das pessoas para de pensar e adiciona isso a um minificador e publica.

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

Aqui está o código reduzido (adicionei as novas linhas)

Minificado usando ( 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
}

Mas todos esses vars, ifs, loops e definições são necessários?

Na maioria das vezes NÃO !

  1. Remova desnecessário if, loop, var
  2. Mantenha uma cópia do seu código original
  3. Use o minificador

OPCIONAL (aumenta o desempenho e código mais curto)

  1. usar operadores taquigráficos
  2. use operadores bit a bit (não use Math)
  3. use a, b, c ... para suas variáveis ​​de temperatura
  4. use a sintaxe antiga ( while, for... não forEach)
  5. use os argumentos da função como espaço reservado (em alguns casos)
  6. remover desnecessário "{}","()",";",spaces,newlines
  7. Use o minificador

Agora, se um minificador pode compactar o código, você está fazendo isso errado.

Nenhum minificador pode compactar corretamente um código incorreto.

faça você mesmo

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

Ele faz exatamente a mesma coisa que os códigos acima.

atuação

http://jsperf.com/diyminify

Você sempre precisa pensar no que você precisa:

Antes de dizer "Ninguém escreveria um código como o abaixo", verifique as primeiras 10 perguntas aqui ...

Aqui estão alguns exemplos comuns que vejo a cada dez minutos.

Quer uma condição reutilizável

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

Alerta sim apenas se existir

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

Alerta sim ou não

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

Converta um número em uma string ou vice-versa

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

Arredondar um número

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

Andar um número

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

caixa de troca

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

tente pegar

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

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

mas indexOfé lento ler este https://stackoverflow.com/a/30335438/2450730

números

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;

Alguns artigos / sites legais que encontrei sobre bit a bit / taquigrafia:

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

http://www.140byt.es/

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

Existem também muitos sites jsperf que mostram o desempenho de shorthand & bitwsie se você pesquisar com seu mecanismo de pesquisa favorito.

Eu poderia fazer um por horas .. mas acho que é o suficiente por agora.

se você tiver alguma dúvida é só perguntar.

E lembre-se

Nenhum minificador pode compactar corretamente um código incorreto.

cocco
fonte
30
Quase não há razão para reduzir o código manualmente. Escreva um código que seja facilmente entendido por outros desenvolvedores (ou por você, 10 meses depois). Sim, mais simples é melhor. Use um minimizado em um processo de construção automatizado que preserva o original. Em quase todos os casos, qualquer ganho de velocidade com a otimização manual é muito, muito superado pelo custo dos desenvolvedores decifrando o código reduzido.
quase
4
depende do que você está fazendo. se você está trabalhando com animações / canvas, grandes conjuntos de dados e manipulação de arquivos, por exemplo, um código rápido é muito importante, especialmente em dispositivos móveis ... o ponto é, para alguns desenvolvedores é difícil de ler. sim ... eu escrevo código desde o pentium 2 .. então provavelmente 1998, eu posso ler o código e na minha experiência tenho menos código para verificar se há erros. E sobre a velocidade .. mh, você está errado. O aumento de desempenho usando bit a bit / e taquigrafia em funções complexas é uma loucura. Especialmente testando em vários dispositivos / navegadores. Use o google shorthandbitwise javascript e você encontrará muitos exemplos
cocco
Ref ao seu exemplo de arredondamento: (10.4899845 +.5)|0resulta em 10 em vez de 11.
DanMan
O código DIY acabou de ser adicionado ao meu arquivo "otimizado demais". Ele NÃO faz exatamente o que o código original faz quando um valor menor que zero é fornecido (myNumber ou a). O código original lança uma exceção e o código "aprimorado" entra em um loop infinito.
Donald Rich
Parece um conselho muito ruim do ponto de vista da capacidade de suporte
donkz,
10

O Google acaba de disponibilizar um compilador javascript que pode minificar seu código, eliminar ramificações de código morto e mais otimizações.

compilador google javascript

Atenciosamente
K

Khb
fonte
3

Junto com a minimização, você também pode codificá-lo em base64. Isso torna seu arquivo muito mais compactado. Tenho certeza que você viu arquivos js que estão dentro de uma função eval () com parâmetros (p, a, c, k, e, r) passados. Eu li neste artigo Como reduzir um arquivo Javascript?

Varg
fonte
A codificação base64 não compacta seu código, ela faz exatamente o oposto, você acaba com mais caracteres. Você pode compactar sua string com LZH, alguém criou um script JS no github que faz compactação LZH em strings chamadas: lz-string, você pode usar isso para compactar seu código: pieroxy.net/blog/pages/lz-string/index.html
beliha
3

Eu escrevi um pequeno script que chama uma API para reduzir o seu script, verifique:

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

Uso:

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

Recentemente, precisei realizar a mesma tarefa. Embora os compressores listados em The JavaScript CompressorRater façam um ótimo trabalho e a ferramenta seja muito útil, os compressores não estavam funcionando bem com alguns códigos jQuery que estou usando (verificações $ .getScript e jQuery.fn). Mesmo o Google Closure Compressor engasgou nas mesmas linhas. Embora eu pudesse ter resolvido as torções, era muito difícil forçar os olhos constantemente.

O que finalmente funcionou sem problemas foi o UglifyJS (obrigado @ Aries51 ), e a compactação foi apenas um pouco menor do que todos os outros. E semelhante ao Google, tem uma API HTTP. O Packer também é bom e tem implementação de linguagem em Perl, PHP e .NET.

Wayne Weibel
fonte
1

Atualmente, existem 2 maneiras de reduzir seu código:

  1. você aplica minificadores no lado de back-end de seu aplicativo - aqui, a vantagem é que você pode aplicar o controle de versão e ter mais controle sobre seu código - você pode automatizar praticamente totalmente o processo de minificação e a prática recomendada seria aplicá-lo antes que seu código seja carregado para o servidor - é melhor usado quando você tem muito código de front-end (a ser reduzido) Javascript e CSS:

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

Muitas dessas ferramentas também estão disponíveis para Node e npm - é uma boa prática automatizar a mnificação de Javascript com Grunt.

  1. você pode usar algumas das ferramentas gratuitas existentes para minificação que estão rodando online - elas praticamente permitem que você faça o mesmo, mas manualmente. Aconselho você a usá-los quando a quantidade de seu código javascript / css for menor - não muitos arquivos

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

PeterBlue
fonte
0

Você pode usar o minificador javascript de ubercompute.com para reduzir o seu código. Ele irá reduzir o seu código javascript em até 75% da versão original.

Abhishek Singh
fonte