如何“最小化” JavaScript代码


99

JQuery有两个可供下载的版本,一个是Production(生产版)(19KB,最小化和压缩),另一个是Development(开发版)(120KB,未压缩的代码)

现在紧凑的19kb版本,如果您下载它,将会看到仍然是javascript可执行代码。他们如何压缩它?我又该如何“缩小”我的代码?


1
尤其是,是否有任何在线实用程序可以让我做到这一点?
KalEl

2
我偶然发现了这个旧帖子,并提出了同样的问题,好问题!一些不错的基本信息:thiscouldbeuseful.com/2012/09/minified-js-for-beginners.html
白羊座2012年

Answers:


48

DIY缩小

没有任何压缩程序可以正确压缩错误代码。

在此示例中,我只想显示一个缩小器的功能。

缩小之前应该做什么

关于jQuery ...我不使用jQuery.jQuery是用于旧浏览器的,它是出于兼容性原因而制作的..检查caniuse.com,几乎所有功能都可以在每个浏览器上使用(也就是ie10已标准化),我认为现在是只是在这里会降低您的Web应用程序的速度...如果愿意,$()您应该创建自己的简单函数。如果客户需要每个人都下载100kb jQuery脚本,为什么还要麻烦压缩代码?您的未压缩代码有多大?5-6kb ..?更不用说添加大量插件以使其变得更容易了。

原始码

当您编写一个函数时,您会有所想法,开始写东西,有时甚至会遇到类似以下代码的代码,这些代码可以正常工作了,现在大多数人停止思考并将其添加到缩小器中并发布它。

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

这是最小的代码(我添加了新行)

使用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
}

但是所有这些vars,ifs,循环和定义是否必要?

大多数时候

  1. 删除不必要的,循环,无功
  2. 保留原始代码的副本
  3. 使用缩小器

可选(提高性能并缩短代码)

  1. 使用简写运算符
  2. 使用按位运算符(不要使用Math
  3. 使用a,b,c ...作为您的临时变量
  4. 使用旧语法(whilefor... not forEach
  5. 使用函数参数作为占位符(在某些情况下)
  6. 删除不必要的 "{}","()",";",spaces,newlines
  7. 使用缩小器

现在,如果压缩程序可以压缩代码,则您做错了。

没有任何压缩程序可以正确压缩错误代码。

自己动手做

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

它与上面的代码完全相同。

性能

http://jsperf.com/diyminify

您始终需要考虑自己的需求:

在您说“没有人会像下面的代码那样编写代码”之前,请先检查此处的前10个问题...

这是我每十分钟看到的一些常见示例。

想要可重用的条件

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

仅在存在时发出警报

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

警报是或否

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

将数字转换为字符串,反之亦然

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

四舍五入

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

楼层数

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

开关盒

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

试着抓

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

如果更多

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

indexOf阅读速度很慢https://stackoverflow.com/a/30335438/2450730

数字

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;

我发现一些有关按位/简写的不错的文章/站点:

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

http://www.140byt.es/

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

如果您使用自己喜欢的搜索引擎进行搜索,那么还有许多jsperf网站显示了简写和bitwsie的性能。

我可以去一个小时。.但是我认为现在已经足够了。

如果您有任何问题,请问。

记住

没有任何压缩程序可以正确压缩错误代码。


30
几乎没有任何理由可以手动缩小代码。编写易于被其他开发人员理解的代码(或者,您在10个月后)。是的,越简单越好。在保留原始内容的自动生成过程中使用缩小版。在几乎每种情况下,手工优化所带来的任何速度收益都远远超过开发人员解密最小化代码的成本。
alttag 2014年

4
取决于你在做什么。例如,如果您使用动画/画布,庞大的数据集和文件处理,快速代码非常重要,尤其是在移动设备上……关键是,对于某些开发人员来说,它很难阅读。是的...我编写代码以来奔腾2 ..大概是1998年,我可以阅读代码,以我的经验,我检查错误的代码也较少。关于速度,.mh,您的错。在复杂的函数中使用按位/和简写可以提高性能,这是疯狂的。在各种设备/浏览器上进行了特别的测试。使用google shorthandbitwise javascript,您会发现很多示例
cocco 2014年

重新您四舍五入例如:(10.4899845 +.5)|0结果在10而不是11
DanMan

DIY代码刚刚添加到我的“过度优化”文件中。当提供小于零的值(myNumber或a)时,它不会完全执行原始代码的操作。原始代码引发异常,而“改进的”代码进入无限循环。
唐纳德·里奇

从可支持性的角度来看,这听起来像是个坏建议
donkz


10

Google刚刚提供了一个JavaScript编译器,它可以减少您的代码,消除无效代码分支并提供更多优化。

Google JavaScript编译器

关于
K


3

除了缩小之外,您还可以对其进行base64编码。它使您的文件更加压缩。我确定您已经看到js文件,这些文件通过参数(p,a,c,k,e,r)封装在eval()函数中。我在本文中阅读了 如何缩小Javascript文件?


base64编码不会压缩您的代码,相反,您最终会得到更多的字符。您可以LZH压缩您的字符串,有人在github上创建了一个JS脚本,该脚本对名为:lz-string的字符串进行LZH压缩,您可以使用它来压缩您的代码:pieroxy.net/blog/pages/lz-string/index.html
beliha

3

我编写了一个微型脚本,该脚本调用API来缩小脚本大小,请检查一下:

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

用法:

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

1

我最近需要执行相同的任务。尽管JavaScript CompressorRater上列出的压缩器做得很好并且该工具非常有用,但这些压缩器在我正在使用的某些jQuery代码($ .getScript和jQuery.fn检查)上的表现并不理想。甚至Google Closure Compressor也处于同一行。虽然我本来可以解决这些问题,但要继续不断地做着眼。

最终没有问题的是UglifyJS(感谢@ Aries51),并且压缩量仅比其他压缩量少一点。与Google类似,它具有HTTP API。 Packer也很好,并且在Perl,PHP和.NET中具有语言实现。


1

当前有两种方法可以减少代码:

  1. 您可以在应用程序的后端应用缩小器-这样做的好处是您可以应用版本控制并且可以更好地控制代码-您几乎可以完全自动化缩小过程,最佳实践是在代码编写之前应用它上载到服务器-当您有大量的前端(待精简)Javascript和CSS代码时,最好使用此方法:

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

Node和npm也可以使用许多这样的工具-使用Grunt自动执行Java脚本的修正是一种很好的做法。

  1. 您可以使用一些在线运行的现有免费缩小工具-实际上,您可以手动执行这些操作。当您的javascript / css代码量较小(文件不多)时,我建议您使用它们

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.