JS Minification:压缩代码

JS Minification: Compressing the code

在线工具(例如 JSCompress)最多可减少 80% 的代码大小。很容易注意到结果 compressed 代码删除了 space。除了删除 EOL 和 ' ' 字符之外,缩小 js 文件是否还需要任何其他技巧?

压缩示例:

function glow(e){$("#"+e).fadeIn(700,function(){$(this).fadeOut(700)})}function startLevel(){ptrn=[],pos=0,setLevel(lvl),$("#mg-lvl").fadeOut("slow",function(){$("#mg-contain").prop("onclick",null).off("click"),$("#mg-contain").css("cursor","default"),$(this).text("Level "+lvl+": "+ptrn.length+" blink(s)."),$(this).fadeIn("slow"),showLevel(0)})}function setLevel(e){ptrn.push(Math.floor(3*Math.random()+1)),0==e||setLevel(--e)}function showLevel(e){$("#b"+ptrn[e]+"c").fadeOut(speed,function(){$("#ball_"+ptrn[e]).fadeOut(speed,function(){$("#b"+ptrn[e]+"c").fadeIn(speed),$(this).fadeIn(speed,function(){e+1<ptrn.length&&showLevel(++e,speed)})})}),e+1==ptrn.length&&setTimeout(bindKeys(1),ptrn.length*speed+15)}function bindKeys(e){for(var e=1;e<4;e++)bind(e)}function bind(e){$("#ball_"+e).on("click",function(){$("#b"+e+"c").fadeOut(speed,function(){$("#ball_"+e).fadeOut(speed,function(){$("#ball_"+e).fadeIn(speed),$("#b"+e+"c").fadeIn(speed),referee(e)&&unbind()})})})}function referee(e){if(pos<ptrn.length&&(e===ptrn[pos]?$("#mg-score").text(parseInt($("#mg-score").text())+1):end()),++pos==ptrn.length)return++lvl,speed-=40,!0}function unbind(){for(var e=1;e<4;e++)$("#ball_"+e).off();startLevel()}function nestedFade(e,n,t){e[n]&&$(e[n]).fadeOut("fast",function(){t[n]&&($(e),t[n]),nestedFade(e,++n,t)})}function end(){for(var e=[],n=[],t=1;t<4;t++)e.push("#b"+t+"c"),e.push("#ball_"+t),n.push(null);e.push("#mg-contain"),n.push('.fadeOut("slow")'),e.push("#mg-obj"),n.push(".fadeOut('slow')"),e.push("#bg-ball-container"),n.push(".toggle()"),nestedFade(e,0,n)}var ptrn=[],pos=0,lvl=1,speed=400,b1=setInterval(function(){glow("ball_1b",700)}),b2=setInterval(function(){glow("ball_2b",700)}),b3=setInterval(function(){glow("ball_3b",700)});

示例未压缩:

var ptrn = [];
var pos = 0;
var lvl = 1;
var speed = 400;

/* make balls glow */
function glow(id)
{
    $('#'+id).fadeIn(700, function(){$(this).fadeOut(700);})
}

var b1 = setInterval(function(){ glow('ball_1b',700) ,1500});
var b2 = setInterval(function(){ glow('ball_2b',700) ,1500});
var b3 = setInterval(function(){ glow('ball_3b',700) ,1500});
/* end */

function startLevel()
{
    ptrn = [];
    pos = 0;

    /* set pattern for the level */
    setLevel(lvl);  

    /* display prompt for level */
    $('#mg-lvl').fadeOut("slow", function(){
        $('#mg-contain').prop('onclick',null).off('click');
        $('#mg-contain').css('cursor','default');
        $(this).text("Level " + lvl + ": " + ptrn.length + " blink(s).");
        $(this).fadeIn('slow');

        /* play back the pattern for user to play */
        showLevel(0); //TODO: use promise and deferred pattern to pull this out of fade function.
    }); 
}

function setLevel(lvl)
{
    ptrn.push(Math.floor((Math.random() * 3) + 1));
    (lvl == 0 ) ? null : setLevel(--lvl);
}

function showLevel(i)
{
    /* blink the balls */
    $('#b'+ptrn[i]+'c').fadeOut(speed, function(){
        $('#ball_'+ptrn[i]).fadeOut(speed, function(){
            $('#b'+ptrn[i]+'c').fadeIn(speed);
            $(this).fadeIn(speed, function(){
                if(i+1<ptrn.length)
                    showLevel(++i,speed);
            });
        });
    });
    if( (i+1) == ptrn.length)
        setTimeout( bindKeys(1), ptrn.length*speed+15) //after the pattern is revealed bind the clicker
}

function bindKeys(i)
{
    for(var i=1;i<4;i++)
        bind(i);
}

function bind(i)
{
    $('#ball_'+i).on('click', function() {      
        $('#b'+i+'c').fadeOut(speed, function() {
            $('#ball_'+i).fadeOut(speed, function() {
                    $('#ball_'+i).fadeIn(speed);
                $('#b'+i+'c').fadeIn(speed);
                if(referee(i))
                    unbind();
            });
        });
    });
}

function referee(val)
{   
    if(pos < ptrn.length){
        ( val === ptrn[pos] ) ? $('#mg-score').text(parseInt($('#mg-score').text())+1) : end();
    }
    if(++pos == ptrn.length)
    {
        ++lvl;
        speed-=40;      
        return true;
    }
}

   function unbind()
    {               
        for(var i=1;i<4;i++)
             $( "#ball_"+i).off();
        startLevel();
    }

function nestedFade(id,i,func)
{
    (!id[i]) ? 0 : $(id[i]).fadeOut('fast',function(){ if(func[i])
{$(id)+func[i];};nestedFade(id,++i,func);}) 
}

function end()
{
    var id = [];
    var func = [];
    for(var i=1;i<4;i++){
    id.push('#b'+i+'c');    
    id.push('#ball_'+i);
    func.push(null)
}

id.push('#mg-contain');
func.push('.fadeOut("slow")');
id.push('#mg-obj');
func.push(".fadeOut('slow')");
id.push('#bg-ball-container');
func.push(".toggle()");

nestedFade(id,0,func);
}

节省 32% 的文件大小...如果是这种情况,那么编写 less 是否是一个合理的假设正在为最终用户做 更多

您可以 'minify' 文件以减小其大小的方式相同,您也可以 'uglify' 文件,它使用您的代码并缩短变量名称之类的内容以达到相同的目的:减少文件通过减少其中的字符数来调整大小(不仅仅是删除换行符和 space 个字符)。

虽然它会减少用户的加载时间,但立即编写 minified/uglified-style 代码并不是一个好的做法。这就是为什么在几乎任何专业的 build/deploy 过程中,您都采用清晰的描述性代码,然后 运行 构建过程以减小文件的大小并最终部署最终用户将有更快时间的版本加载。您始终可以编写您的常规代码,然后 运行 像您描述的那样的压缩过程,将其保存到 "public" 文件夹中并上传供用户访问,而不是您充实的代码。

缩小器所做的只是删除白色 space,正如您所说,它是 ' ' 和 EOL 字符。我相信您可能会想到文件压缩工具,例如 .zip 文件以及您问题的措辞方式。此类文件类型 (.zip) 会在您的文件中找到常见的字符串,并引用原始字符串,而不是将其写出 10 次。这意味着如果字符串 "I like cake" 在您的文件中出现 4 次,它将在一个位置出现 "I like cake",而其他三个位置将引用第一个位置,从而缩短文件的长度并因此减少其长度尺寸。

那么 JS、CSS 和 HTML 缩小的主要原因是当客户端请求网页时减小从服务器传输到客户端的文件的大小。这种尺寸的减小将允许更快的加载时间。因此,从技术上讲,网页加载时间越少越好,但实际上,作为开发人员,您有意识地编写更短的代码以最小化文件大小的效果将是 a.) 最小化更改以实际产生影响或 b.) 导致由于专注于减少代码长度而不是代码质量而导致功能丢失或错误。