极其精简的 JavaScript(js1k 风格)的好资源

发布于 2024-10-04 12:28:40 字数 132 浏览 4 评论 0原文

我确信大多数 JavaScript 开发者都知道,有一个新的圣诞节主题的 js1k。我打算这次参加,但我没有生成如此精简的代码的经验。有谁知道这类事情有什么好的资源吗?

As I'm sure most of the JavaScripters out there are aware, there's a new, Christmas-themed js1k. I'm planning on entering this time, but I have no experience producing such minified code. Does anyone know any good resources for this kind of thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

你是暖光i 2024-10-11 12:28:40

Google Closure Compiler 是一个很好的 JavaScript 压缩器。

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


编辑:添加了一个非详尽的技巧列表,您可以在使用压缩器之前使用这些技巧来极度压缩 JavaScript:

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

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

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

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

删除前导零
0.2 = .2 保存一个字节

Ternery Operator

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

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

Drop Braces
仅当包含多个语句的块时才需要大括号。

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

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

跳出框框思考
不要自动采用标准的做事方式。您可以使用 b.children[4] where d=document 来获取对 DOM 元素的引用,而不是使用 d.getElementById('p') ;b=正文


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

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

Google Closure Compiler is a good javascript minifier.

There is a good online tool for quick use, or you can download the tool and run it as part of a web site build process.


Edit: Added a non-exhaustive list of tricks that you can use to minify JavaScript extremely, before using a minifier:

Shorten long variable names
Use shortened references to built in variables like d=document;w=window.

Set Interval
The setInterval function can take either a function or a string. Pass in a string to reduce the number of characters used: setInterval('a--;b++',10). Note that passing in a string forces an eval invokation so it will be slower than passing in a function.

Reduce Mathematical Calculations
Example a=b+b+b can be reduced to a=3*b.

Use Scientific Notation
10000 can be expressed in scientific notation as 1E4 saving 2 bytes.

Drop leading Zeroes
0.2 = .2 saves a byte

Ternery Operator

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

can be expressed as result=a>b?x:y

Drop Braces
Braces are only required for blocks of more than one statement.

Operator Precedence
Rely on operator precedence rather than adding unneeded brackets which aid code readability.

Shorten Variable Assignment
Rather than function x(){a=1,b=2;...}() pass values into the function, function x(a,b){...}(1,2)

Think outside the box
Don't automatically reach for standard ways of doing things. Rather than using d.getElementById('p') to get a reference to a DOM element, could you use b.children[4] where d=document;b=body.


Original source for above list of tricks:

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

巴黎夜雨 2024-10-11 12:28:40

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

除了 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);
    }
}

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

大多数代码加壳者都知道的东西缩小器不会用较小的标记替换代码中较大的重复标记。这是一个令人讨厌的黑客行为,还需要使用eval,但由于我们是为了空间而参与其中,所以我认为这不应该是一个问题。假设您有以下代码:

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

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

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

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

var a = "eval(''.replace(/function/g,'F'))".length,
    b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");

Spolto is right.
Any code minifier won't do the trick alone. You need to first optimize your code and then make some dirty manual tweaks.

In addition to Spolto's list of tricks I want to encourage the use of logical operators instead of the classical if else syntax. ex:
The following code

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

is somewhat equivalent to

condition&&exp1||exp2;  

Another thing to consider might be multiple variable declaration :

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

can be rewritten as :

var a=c=1,b=2;

Spolto is also right about the braces. You should drop them. But in addition, you should know that they can be dropped even for blocks of more expressions by writing the expressions delimited by a comma(with a leading ; of course) :

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

Can be rewritten as :

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

Although it's not much (it saves you only 1 character/block for those who are counting), it might come in handy. (By the way, the latest Google Closure Compiler does this trick too).

Another trick worth mentioning is the controversial with functionality.
If you care more about the size, then you should use this because it might reduce code size.
For example, let's consider this object method:

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

This can be rewritten as :

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

which is in most cases signifficantly smaller.

Something that most code packers & minifiers do not do is replacing large repeating tokens in the code with smaller ones. This is a nasty hack that also requires the use of eval, but since we're in it for the space, I don't think that should be a problem. Let's say you have this code :

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

This code has many "function" keywords repeating. What if you could replace them with a single(unused) character and then evaluate the code?
Here's how I would do it :

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

Of course the replaced token(s) can be anything since our code is reduced to an evaluated string (ex: we could've replaced =function(){ with F, thus saving even more characters).
Note that this technique must be used with caution, because you can easily screw up your code with multiple text replacements; moreover, you should use it only in cases where it helps (ex: if you only have 4 function tokens, replacing them with a smaller token and then evaluating the code might actually increase the code length :

var a = "eval(''.replace(/function/g,'F'))".length,
    b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
梦纸 2024-10-11 12:28:40

在下面的链接中,您会发现一些令人惊讶的好技巧来缩小本次比赛的 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/字节节省技术

In the following link you'll find surprisingly good tricks to minify js code for this competition:

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

One example: (extracted from section Short-circuit operators):

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

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

Or the more essoteric Canvas context hash trick:

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

And here is another resource link with amazingly good tricks: https://github.com/jed/140bytes/wiki/Byte-saving-techniques

挽手叙旧 2024-10-11 12:28:40

首先,仅仅将代码放入压缩器中不会有太大帮助。编写代码时需要考虑到极小的文件大小。所以在某种程度上,你需要自己学习所有的技巧。

另外,当谈到压缩器时, UglifyJS 是这里的新流星,它的输出比 GCC 的小,并且它也快得多。由于它是用纯 JavaScript 编写的,因此您应该很容易找出它应用的所有技巧。

但最终,一切都取决于您能否找到一个智能的、小型的解决方案来完成一些很棒的事情。

First off all, just throwing your code into a minifier won't help you that much. You need to have the extreme small file size in mind when you write the code. So in part, you need to learn all the tricks yourself.

Also, when it comes to minifiers, UglifyJS is the new shooting star here, its output is smaller than GCC's and it's way faster too. And since it's written in pure JavaScript it should be trivial for you to find out what all the tricks are that it applies.

But in the end it all comes down to whether you can find an intelligent, small solution for something that's awsome.

时光暖心i 2024-10-11 12:28:40

一位朋友为 js1k 编写了 jscrush 打包程序。

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

我的极限包装工作流程是:闭合(漂亮的打印)->手工优化、功能相似度、其他代码相似度->闭包(仅限空白)-> jsrush。

这会带走大约 25% 的数据。

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

A friend wrote jscrush packer for js1k.

Keep in mind to keep as much code self-similar as possible.

My workflow for extreme packing is: closure (pretty print) -> hand optimizations, function similarity, other code similarity -> closure (whitespace only) -> jscrush.

This packs away about 25% of the data.

There's also packify, but I haven't tested that myself.

一曲琵琶半遮面シ 2024-10-11 12:28:40

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

http://iwantaneff.in/packer/

非常方便打包/压缩 JS

This is the only online version of @cowboy's packer script:

http://iwantaneff.in/packer/

Very handy for packing / minifying JS

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文