English 中文(简体)
How to minify Javascript code
原标题:

JQuery has two versions for download, one is Production (19KB, Minified and Gzipped), and the other is Development (120KB, Uncompressed Code).

Now the compact 19kb version, if you download it, you will see is still a javascript executable code. How did they compactify it? And how can I minify my code like that too?

问题回答

DIY Minification

No minifier can compress properly a bad code.

In this example i just wanna show how much a minifier does.

What you should do before you minify

And regarding jQuery... i don t use jQuery.jQuery is for old browsers,it was made for compatibility reasons .. check caniuse.com, almost everything works on every browser (also ie10 is standardized now) , i think now it s just here to slow down your web application...if you like the $() you should create your own simple function.And why bother to compress your code if your clients need to download the 100kb jquery script everythime?how big is your uncompressed code? 5-6kb..? Not to talk about the tons of plugins you add to to make it easier.

Original Code

When you write a function you have an idea, start to write stuff and sometimes you end up with something like the following code.The code works.Now most people stop thinking and add this to a minifier and publish it.

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

Here iss the minified code (i added the new lines)

Minified using (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
}

But are all those vars , ifs, loops & definitions necessary?

Most of the time NO !

  1. Remove unnecessary if,loop,var
  2. Keep a copy of your original code
  3. Use the minifier

OPTIONAL (increases the performance & shorter code)

  1. use shorthand operators
  2. use bitwise operators (don t use Math)
  3. use a,b,c... for your temp vars
  4. use the old syntax (while,for... not forEach)
  5. use the function arguments as placeholder (in some cases)
  6. remove unneccessary "{}","()",";",spaces,newlines
  7. Use the minifier

Now if a minifier can compress the code your doing it wrong.

No minifier can compress properly a bad code.

DIY

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

It does exactly the same thing as the codes above.

Performance

http://jsperf.com/diyminify

You always need to think what you need:

Before you say "Noone would write code like the one below" go and check the first 10 questions in here ...

Here are some common examples i see every ten minutes.

Want a reusable condition

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

Alert yes only if it exists

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 yes or 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

Convert a number to a string or 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

Round a number

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

Floor a number

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

switch case

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

try catch

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

more if

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

but indexOf is slow read this https://stackoverflow.com/a/30335438/2450730

numbers

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;

Some nice articles/sites i found about 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/

There are also many jsperf sites showing the performance of shorthand & bitwsie if you search with your favorite searchengine.

I could go one for hours.. but i think it s enough for now.

if you have some questions just ask.

And remember

No minifier can compress properly a bad code.

You could use one of the many available javascript minifiers.

Google just made available a javascript compiler that can minify your code, elimiated dead code branches and more optimizations.

google javascript compiler

Regards
K

If you are using the VSCode editor, there are lots of plugins/extensions available.

The MinifyAll for instance is a very good one - compatible with many extension.

Install it and reload VSCode. Then click on your file, open command palette (Ctrl+Shift+p), ant type minify this document (Ctrl+alt+m) other available options there also like preserve original document and so on! Easy!

I recently needed to perform the same task. While the compressors listed at The JavaScript CompressorRater do a great job and the tool is very useful, the compressors were not playing nice with some jQuery code I am using ($.getScript and jQuery.fn checks). Even the Google Closure Compressor choked on the same lines. While I could have eventually ironed out the kinks it was far to much squinting to do constantly.

The one that finally worked without issue was UglifyJS (thanks @Aries51), and the compression was only slightly less than all the others. And similar to Google it has a HTTP API. Packer is also nice and has language implementation in Perl, PHP, and .NET.

Along with minifying you can base64 encode it too. It makes your file much more compressed. I m sure you have seen js files that are wrapped inside an eval() function with parameters (p,a,c,k,e,r) passed. I read it in this article How to Minify a Javascript File?

I have written a tiny script which calls a API to get your script minified, check it out:

#!/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 "
Output: $output_filename";

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

            printf( "Size reduction %.02f%%

", ( ( $sz_org - $sz_wr ) / $sz_org ) * 100 );
        }   
        close($fh);
    }
    else {
      warn: "Error: $file : " . $resp->status_line;
    }
}

Usage:

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

There are currently 2 ways of minifying your code:

  1. you apply minifiers at the backend side of your application - here the advantage is that you can apply versioning and are more in control of your code - you can practically fully automate the process of minification and best practice would be to apply it before your code is uploaded to the server - this is best used when you have a lot of frontend (to be minified) Javascript and CSS code:

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

Many such tools are available for Node and npm as well - it s good practice to automate the mnification of Javascript with Grunt.

  1. you can use some of the existing free tools for minification that are running online - these practically allow you to do the same, but manually. I would advice you to use them when the amount of your javascript / css code is smaller - not many files

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

You can use javascript minifier of ubercompute.com to minify your code, It will minify your javascript code upto 75% of their original version.

Try out this JavaScript minifier from fixcode.org. It s a very effective tool to minify JavaScript

  • Import code via URL
  • import from file
  • copy/download output




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签