10

我相信大多数 JavaScript 开发者都知道,有一个新的、以圣诞节为主题的 js1k。我计划进入这个时间,但我没有生成这种缩小代码的经验。有谁知道这种事情的任何好资源?

4

7 回答 7

14

Google Closure Compiler是一个很好的 javascript minifier。

有一个很好的在线工具可以快速使用,或者您可以下载该工具并将其作为网站构建过程的一部分运行。


编辑:在使用缩小器之前,添加了一个非详尽的技巧列表,可用于极度缩小 JavaScript:

缩短长变量名
使用对内置变量的缩短引用,如d=document;w=window.

设置间隔
setInterval函数可以采用函数或字符串。传入一个字符串以减少使用的字符数:setInterval('a--;b++',10). 请注意,传入字符串会强制执行 eval 调用,因此它比传入函数要慢。

减少数学计算
示例a=b+b+b可以减少到a=3*b

使用科学计数法
10000可以用科学计数法表示为1E4节省 2 个字节。

删除前导零
0.2 = .2可以节省一个字节

三元运算符

if (a > b) {
     result = x;
}
else {
  result = y;
}

可以表示为result=a>b?x:y


括号 大 括号仅对多于一条语句的块是必需的。

运算符优先级
依靠运算符优先级而不是添加有助于代码可读性的不需要的括号。

缩短变量赋值
而不是function x(){a=1,b=2;...}()将值传递给函数,function x(a,b){...}(1,2)

跳出框框思考
不要自动寻求标准的做事方式。d.getElementById('p')与其使用来获取对 DOM 元素的引用,不如使用b.children[4]where d=document;b=body


上述技巧列表的原始来源:

http://thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/

于 2010-11-27T14:42:41.963 回答
4

斯波尔托是对的。
任何代码压缩器都无法单独完成任务。您需要首先优化您的代码,然后进行一些肮脏的手动调整。

除了 Spolto 的技巧列表之外,我还想鼓励使用逻辑运算符而不是经典if else语法。例如:
以下代码

if(condition){
    exp1;
}else{
    exp2;
}

有点等价于

condition&&exp1||exp2;  

要考虑的另一件事可能是多变量声明

var a = 1;var b = 2;var c = 1;

可以改写为:

var a=c=1,b=2;

Spolto 对牙套的看法也是正确的。你应该放下它们。但此外,您应该知道,通过编写由逗号分隔的表达式(当然,以;开头) ,即使是更多表达式块也可以删除它们:

if(condition){
    exp1;
    exp2;
    exp3;
}else{
    exp4;
    exp5;
}

可以改写为:

 if(condition)exp1,exp2,exp3;
 else exp4,exp5;

虽然它并不多(它只为那些计算的人节省了 1 个字符/块),但它可能会派上用场。(顺便说一句,最新的Google Closure Compiler也可以做到这一点)。

另一个值得一提的技巧是有争议的with功能。
如果您更关心大小,那么您应该使用它,因为它可能会减少代码大小。
例如,让我们考虑这个对象方法:

object.method=function(){
    this.a=this.b;
    this.c++;
    this.d(this.e);
}

这可以重写为:

object.method=function(){
    with(this){
        a=b;
        c++;
        d(e);
    }
}

在大多数情况下,它要小得多。

大多数代码打包器和压缩器不做的事情是将代码中的大重复标记替换为较小的标记。这是一个令人讨厌的 hack,也需要使用eval,但由于我们在其中是为了空间,我认为这不应该是一个问题。假设您有以下代码:

a=function(){/*code here*/}; 
b=function(){/*code here*/};
c=function(){/*code here*/};
/*...*/
z=function(){/*code here*/};

此代码有许多重复的“功能”关键字。如果您可以用单个(未使用的)字符替换它们然后评估代码怎么办?
这是我的做法:

eval('a=F(){/*codehere*/};b=F(){/*codehere*/};c=F(){/*codehere*/};/*...*/z=F(){/*codehere*/};'.replace(/function/g,'F'));

当然,被替换的标记可以是任何东西,因为我们的代码被简化为评估字符串(例如:我们可以用F替换=function(){,从而节省更多字符)。 请注意,必须谨慎使用此技术,因为您可以很容易地用多个文本替换来搞砸您的代码;此外,您应该仅在有帮助的情况下使用它(例如:如果您只有4 个函数标记,则用较小的标记替换它们然后评估代码实际上可能会增加代码长度:

var a = "eval(''.replace(/function/g,'F'))".length,
    b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
于 2012-02-10T10:43:59.943 回答
4

在下面的链接中,您会发现为这场比赛缩小 js 代码的惊人好技巧:

http://www.claudiocc.com/javascript-golfing/

一个例子:(摘自短路运算符部分):

if (p) p=q;  // before
p=p&&q;      // after

if (!p) p=q; // before
p=p||q;      // after

或者更深奥的Canvas 上下文哈希技巧

// before
a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc                                  

// after
for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac

这是另一个具有惊人技巧的资源链接:https ://github.com/jed/140bytes/wiki/Byte-saving-techniques

于 2014-03-04T06:40:04.153 回答
2

首先,仅仅将你的代码扔进一个缩小器不会对你有太大帮助。编写代码时,您需要考虑到极小的文件大小。因此,在某种程度上,您需要自己学习所有技巧。

此外,说到缩小器,UglifyJS是这里的新星,它的输出比 GCC 小,而且速度也更快。而且由于它是用纯 JavaScript 编写的,因此您应该很容易找出它适用的所有技巧。

但归根结底,这一切都归结为您能否找到一个智能的、小型的解决方案来解决令人讨厌的问题。

于 2010-11-27T15:01:58.967 回答
2

还:

Dean Edwards Packer http://dean.edwards.name/packer/

丑化 JS http://marijnhaverbeke.nl/uglifyjs

于 2013-05-10T18:12:17.223 回答
1

一个朋友为 js1k 写了jscrush packer。

请记住尽可能多地保持代码自相似。

我极端打包的工作流程是:闭包(漂亮的印刷品)-> 手部优化、功能相似性、其他代码相似性-> 闭包(仅限空白)-> jscrush。

这包含了大约 25% 的数据。

还有packify,但我自己没有测试过。

于 2011-04-23T18:01:14.743 回答
1

这是@cowboy的打包脚本的唯一在线版本:

http://iwantaneff.in/packer/

非常方便打包/缩小 JS

于 2013-05-10T17:56:46.587 回答