Cómo 'minificar' el código Javascript

99

JQuery tiene dos versiones para descargar, una es Producción (19KB, Minified y Gzip) , y la otra es Desarrollo (120KB, Código sin comprimir) .

Ahora la versión compacta de 19kb, si la descarga, verá que sigue siendo un código ejecutable javascript. ¿Cómo lo compactaron? ¿Y cómo puedo 'minificar' mi código así también?

KalEl
fuente
1
Especialmente, ¿hay alguna utilidad en línea que me permita hacer esto?
KalEl
2
Me topé con esta publicación anterior con las mismas preguntas, ¡tan buena pregunta! Alguna buena información básica: thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html .
Aries51

Respuestas:

48

Minificación de bricolaje

Ningún minificador puede comprimir correctamente un código incorrecto.

En este ejemplo, solo quiero mostrar cuánto hace un minificador.

Qué debes hacer antes de minificar

Y con respecto a jQuery ... no uso jQuery.jQuery es para navegadores antiguos, se hizo por razones de compatibilidad ... revisa caniuse.com, casi todo funciona en todos los navegadores (también ie10 está estandarizado ahora), creo que ahora es solo aquí para ralentizar su aplicación web ... si lo desea $(), debe crear su propia función simple. ¿Y por qué molestarse en comprimir su código si sus clientes necesitan descargar el script jquery de 100kb cada vez? ¿Qué tan grande es su código sin comprimir? 5-6kb ..? Por no hablar de las toneladas de complementos que agrega para hacerlo más fácil.

Codigo original

Cuando escribes una función tienes una idea, empiezas a escribir cosas y a veces terminas con algo como el siguiente código. El código funciona. Ahora la mayoría de la gente deja de pensar y agrega esto a un minificador y lo 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;
}

Aquí está el código minificado (agregué las nuevas líneas)

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
}

Pero, ¿son necesarios todos esos vars, ifs, bucles y definiciones?

La mayoría de las veces ¡ NO !

  1. Eliminar innecesario if, loop, var
  2. Guarde una copia de su código original
  3. Usa el minificador

OPCIONAL (aumenta el rendimiento y acorta el código)

  1. utilizar operadores taquigráficos
  2. usar operadores bit a bit (no usar Math)
  3. usa a, b, c ... para tus vars temporales
  4. usa la sintaxis antigua ( while, for... no forEach)
  5. usar los argumentos de la función como marcador de posición (en algunos casos)
  6. eliminar innecesario "{}","()",";",spaces,newlines
  7. Usa el minificador

Ahora, si un minificador puede comprimir el código, lo estás haciendo mal.

Ningún minificador puede comprimir correctamente un código incorrecto.

Bricolaje

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

Hace exactamente lo mismo que los códigos anteriores.

Actuación

http://jsperf.com/diyminify

Siempre debes pensar en lo que necesitas:

Antes de decir "Nadie escribiría un código como el que se muestra a continuación", revise las primeras 10 preguntas aquí ...

Aquí hay algunos ejemplos comunes que veo cada diez minutos.

Quiere una condición reutilizable

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

Alerta sí solo si existe

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 si 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

Convertir un número en una cadena 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

Redondea un 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)

Piso un número

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

caso de interruptor

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

trata de atraparlo

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

mas si

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

pero indexOfes lento lea esto 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;

Algunos buenos artículos / sitios que encontré sobre bit a bit / taquigrafía:

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

http://www.140byt.es/

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

También hay muchos sitios jsperf que muestran el rendimiento de taquigrafía y bitwsie si busca con su motor de búsqueda favorito.

Podría ir a uno durante horas ... pero creo que es suficiente por ahora.

si tiene algunas preguntas, pregunte.

Y recuerda

Ningún minificador puede comprimir correctamente un código incorrecto.

coco
fuente
30
Casi no hay razón para minificar manualmente el código. Escriba código que otros desarrolladores entiendan fácilmente (o usted, 10 meses después). Sí, cuanto más simple, mejor. Utilice un proceso de construcción minificado en un automatizado que conserva el original. En casi todos los casos, cualquier ganancia de velocidad derivada de la optimización manual se ve superada por el costo de los desarrolladores que descifran el código minificado.
alttag
4
depende de lo que estés haciendo. Si trabajas con animaciones / lienzo, conjuntos de datos enormes y manipulación de archivos, por ejemplo, un código rápido es muy importante, especialmente en dispositivos móviles ... el punto es que para algunos desarrolladores es difícil de leer, sí ... escribo código desde el pentium 2 .. probablemente 1998, puedo leer el código y en mi experiencia tengo menos código para comprobar si hay errores. Y sobre la velocidad .. mh, estás equivocado. El rendimiento aumenta usando bit a bit / y taquigrafía en funciones complejas es una locura. Especialmente las pruebas en varios dispositivos / navegadores. Utilice google shorthandbitwise javascript y encontrará muchos ejemplos
Cocco
Re su ejemplo de redondeo: (10.4899845 +.5)|0resulta en 10 en lugar de 11.
DanMan
El código de bricolaje se acaba de agregar a mi archivo "sobre optimizado". NO hace exactamente lo que hace el código original cuando se proporciona un valor menor que cero (myNumber o a). El código original lanza una excepción y el código "mejorado" entra en un bucle infinito.
Donald Rich
Eso suena como un mal consejo desde la perspectiva de la compatibilidad
donkz
10

Google acaba de poner a disposición un compilador de JavaScript que puede minimizar su código, eliminar ramas de código inactivas y más optimizaciones.

compilador javascript de google

Saludos
K

Khb
fuente
3

Junto con la minificación, también puede codificarlo en base64. Hace que su archivo esté mucho más comprimido. Estoy seguro de que ha visto archivos js que están empaquetados dentro de una función eval () con parámetros (p, a, c, k, e, r) pasados. Lo leí en este artículo ¿Cómo minificar un archivo Javascript?

Varg
fuente
La codificación base64 no comprime su código, hace exactamente lo contrario, termina con más caracteres. Puede LZH Comprimir su cadena, alguien creó un script JS en github que realiza la compresión LZH en cadenas llamadas: lz-string, puede usar eso para comprimir su código: pieroxy.net/blog/pages/lz-string/index.html
beliha
3

He escrito un pequeño script que llama a una API para minificar su script, compruébelo:

#!/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
fuente
1

Recientemente necesitaba realizar la misma tarea. Si bien los compresores enumerados en The JavaScript CompressorRater hacen un gran trabajo y la herramienta es muy útil, los compresores no funcionaban bien con el código jQuery que estoy usando ($ .getScript y jQuery.fn controles). Incluso el compresor de cierre de Google se ahogó en las mismas líneas. Si bien eventualmente podría haber solucionado los problemas, era mucho entrecerrar los ojos para hacer constantemente.

El que finalmente funcionó sin problemas fue UglifyJS (gracias @ Aries51 ), y la compresión fue solo un poco menor que todas las demás. Y similar a Google, tiene una API HTTP. Packer también es bueno y tiene implementación de lenguaje en Perl, PHP y .NET.

Wayne Weibel
fuente
1

Actualmente hay 2 formas de minificar su código:

  1. aplica minificadores en el lado del backend de su aplicación; aquí la ventaja es que puede aplicar el control de versiones y tiene más control de su código; puede automatizar prácticamente por completo el proceso de minificación y la mejor práctica sería aplicarlo antes de que su código sea subido al servidor: esto se usa mejor cuando tiene una gran cantidad de código JavaScript y CSS frontend (para ser minificado):

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

Muchas de estas herramientas también están disponibles para Node y npm; es una buena práctica automatizar la mnificación de Javascript con Grunt.

  1. Puede usar algunas de las herramientas gratuitas existentes para la minificación que se ejecutan en línea; estas prácticamente le permiten hacer lo mismo, pero manualmente. Le aconsejo que los use cuando la cantidad de su código javascript / css sea menor, no muchos archivos

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

PeterBlue
fuente
0

Puede usar el minificador de javascript de ubercompute.com para minimizar su código. Minimizará su código de javascript hasta un 75% de su versión original.

Abhishek Singh
fuente