【问题标题】:How to 'minify' Javascript code如何“缩小”Javascript代码
【发布时间】:2010-12-16 18:44:47
【问题描述】:

JQuery有两个版本可供下载,一个是Production (19KB, Minified and Gzipped),另一个是Development (120KB, Uncompressed Code)

现在是 19kb 的精简版,如果你下载它,你会看到仍然是一个 javascript 可执行代码。他们是如何压缩它的?我怎样才能像那样“缩小”我的代码?

【问题讨论】:

标签: javascript gzip


【解决方案1】:

您可以使用众多可用的 javascript 缩小器之一。

【讨论】:

【解决方案2】:

Google 刚刚提供了一个 javascript 编译器,可以缩小您的代码、消除死代码分支并进行更多优化。

google javascript compiler

问候

【讨论】:

    【解决方案3】:

    我最近需要执行相同的任务。虽然The JavaScript CompressorRater 列出的压缩器做得很好并且该工具非常有用,但压缩器在我使用的一些 jQuery 代码($.getScript 和 jQuery.fn 检查)上表现不佳。甚至Google Closure Compressor 也被同样的线路呛住了。虽然我本可以最终解决这些问题,但要经常眯着眼睛做这件事是远远不够的。

    最终没有问题的工作是UglifyJS(感谢@Aries51),压缩率仅略低于其他所有。与谷歌类似,它有一个 HTTP API。 Packer 也不错,在 Perl、PHP 和 .NET 中实现了语言。

    【讨论】:

      【解决方案4】:

      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
      }
      

      但是所有这些变量、ifs、循环和定义都是必要的吗?

      大多数时候

      1. 删除不必要的 if,loop,var
      2. 保留原始代码的副本
      3. 使用缩小器

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

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

      现在,如果缩小器可以压缩代码,那么你做错了。

      没有缩小器可以正确压缩坏代码。

      DIY

      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 的性能。

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

      如果您有任何问题,尽管问。

      记住

      没有缩小器可以正确压缩坏代码。

      【讨论】:

      • 几乎没有任何理由手动缩小代码。编写其他开发人员(或您,10 个月后)易于理解的代码。是的,越简单越好。在保留原始文件的自动构建过程中使用缩小版。几乎在每种情况下,手动优化带来的任何速度提升都远远超过开发人员破译压缩代码的成本。
      • 取决于你在做什么。例如,如果您使用动画/画布、庞大的数据集和文件操作,那么快速的代码非常重要,尤其是在移动设备上……关键是,对于某些开发人员来说,它很难阅读。是的……我写代码是因为奔腾2 ..所以可能是1998年,我可以阅读代码,根据我的经验,我检查错误的代码更少。关于速度..嗯,你错了。在复杂函数中使用按位/简写来提高性能是很疯狂的。特别是在各种设备/浏览器上进行测试。使用 google shorthandbitwise javascript,你会发现很多例子
      • 重新您的舍入示例:(10.4899845 +.5)|0 结果为 10 而不是 11。
      • DIY 代码刚刚添加到我的“过度优化”文件中。当提供小于零的值(myNumber 或 a)时,它不会完全执行原始代码的操作。原始代码抛出异常,“改进”代码进入无限循环。
      • 从可支持性的角度来看,这听起来像是一个糟糕的建议
      【解决方案5】:

      除了缩小之外,您还可以对其进行 base64 编码。它使您的文件更加压缩。我确定您已经看到了包装在 eval() 函数中并传递参数 (p,a,c,k,e,r) 的 js 文件。我在这篇文章里读到了How to Minify a Javascript File?

      【讨论】:

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

      目前有两种方法可以缩小代码:

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

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

      许多此类工具也可用于 Node 和 npm - 使用 Grunt 自动化 Javascript 的 mnification 是一种很好的做法。

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

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

      【讨论】:

      【解决方案7】:

      我写了一个小脚本,它调用一个 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 [..]
      

      【讨论】:

        【解决方案8】:

        您可以使用 ubercompute.com 的javascript minifier 来缩小您的代码,它会将您的 JavaScript 代码缩小到原始版本的 75%。

        【讨论】:

        • 无法作为网站本身面临的问题。当尝试上传文件上传按钮不起作用。
        • 感谢@MohitSwami 告知我们该错误,但您没有报告此类错误,但由于服务器临时中断,您可能会发生这种错误。
        • 是的,这是由于服务器临时中断。它现在正在工作。谢谢。
        【解决方案9】:

        如果您使用的是 VSCode 编辑器,则有很多可用的插件/扩展。

        例如MinifyAll 是一个非常好的 - 与许多扩展兼容。

        安装它并重新加载 VSCode。然后点击你的文件,打开命令面板(Ctrl+Shift+p),ant type minify this document(Ctrl+alt+m)其他可用的选项还有保留原始文件等等!简单!

        【讨论】:

          【解决方案10】:

          fixcode.org 试试这个JavaScript minifier。 它是缩小 JavaScript 的非常有效的工具

          • 通过 URL 导入代码
          • 从文件导入
          • 复制/下载输出

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-08-14
            • 1970-01-01
            • 1970-01-01
            • 2014-09-17
            • 2011-01-11
            相关资源
            最近更新 更多