背景

前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件。

如今主流的Js代码压缩工具主要有:

1)Uglify http://lisperator.net/uglifyjs/

2)YUI Compressor http://developer.yahoo.com/yui/compressor/

3)Google Closure Compiler https://developers.google.com/closure/compiler/

自从jQuery等流行库使用Uglify作为压缩工具,Uglify慢慢流行起来,如今也是很多开发工具(框架)默认使用的Js压缩工具,比如百度的Fis以及绝大部分的Yeoman脚手架等。YUI Compressor也逐渐被Uglify所替代。

Uglify的压缩策略较为安全,所以不会对源代码进行大幅度的改造,压缩相对较为保守。所以将通过Uglify压缩后的代码格式化之后,还是大致能看明白。

而Google Closure Compiler(以下简称GCC)的高级压缩则是完全重新改造JS代码,去除代码中一些可以直接输出运行结果的逻辑,去除根根本不会执行到的JS代码,从而压缩效率会更高。

GCC三种压缩模式

GCC提供三种压缩模式:

1)Whitespace only
2)Simple
3)Advanced

我们以这段简单的代码为例

function sayHello(name) {
alert('Hello, ' + name);
}
sayHello('binnng');

分别使用这三种压缩模式进行压缩:

Whitespace only

function sayHello(name){alert("Hello, "+name)}sayHello("binnng");

发现只是简单的去除空格换行注释。

Simple

function sayHello(a){alert("Hello, "+a)}sayHello("binnng");

Whitespace only要高端一点,在其基础上,还对局部变量的变量名进行缩短。这也是其他压缩工具所使用的压缩方式,如Uglify等,也是最为主流的压缩方式。比较安全。

Advanced

alert("Hello, binnng");

会发现,Advanced级别的压缩改变(破坏)了原有代码结构,直接输出了代码最终运行结果,可见的确是分析重写破坏,但是对代码压缩做到了极致,极大的减少了代码量。

注意的地方

正因为GCC是这样的破坏性压缩工具,所以使用起来得异常小心,稍微不规范可能就会引起压缩报错或者压缩成功后却不能正常运行。那么,如果要使用Advanced级别压缩,要注意哪些呢?

以下所有未指名级别的GCC压缩均为Advanced级别。

GCC会对变量的属性名也进行压缩

var data = {
user: "binnng",
age: "18"
}; if ("user" in data) {
alert(data.age);
}

经过Uglify压缩:

var data={user:"binnng",age:"18"};"user"in data&&alert(data.age);

经过GCC压缩:

var a={b:"binnng",a:"18"};"user"in a&&alert(a.a);

会发现GCC压缩时,将变量的属性名也缩短,代码量减少了,但是却带来了问题,会发现以上GCC压缩后的代码运行其实是不正确的。因为属性名缩短改变后,data已经不再拥有名为user的属性了。

那如何解决呢?

var data = {
user: "binnng",
age: "18"
}; if (data.user) {
alert(data.age);
}

这时候再经过GCC压缩:

alert("18");

直接输出了正确的结果。

如果不想让GCC压缩属性名,比如在Ajax请求发送给后端接口的时候,可以将属性名用双引号包裹:

var data = {
"user": "binnng",
"age": "18"
}; var ajax = function(url, data, callback) {
(new window.XMLHttpRequest()).send(data);
// ...
}; ajax("//baidu.com", data, function(res) {console.log(res)});

这样经过GCC压缩后:

(new window.XMLHttpRequest).send({user:"binnng",age:"18"});

原封不动的保留了后端需要的参数名。

全局变量要显式挂载在window下

var foo = "1234";
alert(widnow.foo);

这时候,经过GCC压缩后:

alert(window.a);

有点莫名其妙。。因为在GCC中,不再认可隐式全局变量,所以上面的代码中在GCC眼里,foo是没有挂载到window下的,所以下文的window.foo其实是未定义的。

要解决这个问题,必须将foo显式挂载到window下:

window.foo = "1234";
alert(widnow.foo);

这样经过压缩后:

window.a="1234";alert(widnow.a);

这时候可能就会疑问,为何不直接压缩成alert("1234")呢?这是因为GCC不会去除挂载在window下的变量

必要时导出变量函数等

window.btnClick = function() {
alert("clicked");
};

以上的代码经过压缩后成为:

window.a=function(){alert("clicked")};

此时,如果HTML中存在如下代码,就会报错。

<a onclick="btnClick()">点我</a>

这时候就需要导出函数

window["btnClick"] = function() {
alert("clicked");
};

用双引号包裹后,btnClick就保留了下来。在构造函数中,尤其需要注意导出,例如:

var Animal = function(name) {
this.name = name;
};
Animal.prototype.eat = function() {
alert(this.name + " is eating!");
};

以上的代码经过GCC压缩后,什么都没剩下,因为GCC认为,代码中的代码都没有执行,属于dead code。既然这么写了,那肯定是需要它,提供给别人外部调用什么的,这时候就需要这么导出:

var Animal = function(name) {
this.name = name;
};
Animal.prototype.eat = function() {
alert(this.name + " is eating!");
}; window["Animal"] = Animal;
Animal.prototype["eat"]= Animal.prototype.eat;

经过压缩后:

function a(b){this.name=b}a.prototype.a=function(){alert(this.name+" is eating!")};window.Animal=a;a.prototype.eat=a.prototype.a;

这时候,Animal这个方法成功的保留了下来。

还有,在使用JSONP方式获取服务端数据的时候,也一定要导出callback方法名:

var jsonpCb = function() {
//...
}; getScript("/api/data?callback=jsonpCb"); // 导出,否则jsonpCb会被压缩掉不能被识别
window["jsonpCb"] = jsonpCb;

所有业务代码合并压缩

a.js

var getName = function() {return "binnng"};

b.js

alert(getName());

如果单独压缩a.jsb.js就会出问题,结果会是a.js中什么都没有,b.jsgetName方法未定义(undefined)。正确的做法则是,两者合并再进行压缩。

结语

GCC的高级压缩(Advanced)非常强大,对代码压缩做到了极致,但是其对代码书写要求也比较严格,并且破坏性压缩也被很多开发者所诟病。

但是稍加注意,严格规范自身代码风格,了解GCC压缩方式原理,利用好GCC高级压缩,一定会大大减少JS的体积,从而大幅度的提升前端代码性能。

另外,GCC像其他压缩工具一样,也有GruntGulp构建组件,可以很方便的去使用它。

参考

https://developers.google.com/closure/compiler/ (需FQ)

使用Google Closure Compiler高级压缩Javascript代码的更多相关文章

  1. 使用Google Closure Compiler高级压缩Javascript代码注意的几个地方

    介绍 GCC(Google Closure Compiler)是由谷歌发布的Js代码压缩编译工具.它可以做到分析Js的代码,移除不需要的代码(dead code),并且去重写它,最后再进行压缩. 三种 ...

  2. Google Closure Compiler高级压缩混淆Javascript代码

    一.背景 前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件. 如今主流的Js代码压缩工具主要有: 1)Uglify http://lisperator.net/uglifyj ...

  3. 使用Google Closure Compiler全力压缩代码(转)

    JavaScript压缩代码的重要性不言而喻,如今的压缩工具也有不少,例如YUI Compressor,Google Closure Compiler,以及现在比较红火的UglifyJS.Uglify ...

  4. Google Closure Compiler 高级模式及更多思考(转)

    前言 Google Closure Compiler 是 Google Closure Tools 的一员,在 2009 年底被 Google 释出,早先,有 玉伯 的 Closure Compile ...

  5. JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法

    网上搜索了,目前主流的Js代码压缩工具主要有Uglify.YUI Compressor.Google Closure Compiler,简单试用了UglifyJS 和Google Closure Co ...

  6. bootstrap-datetimepicker在经过GC(Google Closure Compiler)压缩后无法使用的解决方案

    将压缩级别由simple改成whitespace 问题就是这样之后压缩后的文件大了很多 <?xml version="1.0"?> <project name=& ...

  7. Gulp压缩JavaScript代码

    因为gulp是自动化工具,所以我们得告诉它,需要怎么做,才能达到我们的目的. 我们首先得新建一个js文件,用来编写我们的需求,以便gulp能按着我们的意愿来执行. 我将这个js文件取名叫gulpfil ...

  8. Grunt 使用(二)uglify插件压缩javascript代码

    本文在配置grunt基本环境的基础下,讲解如何使用grunt-contrib-uglify进行javascript压缩 本文只介绍了grunt-contrib-uglify插件的一种压缩方式适用于大部 ...

  9. 【Java】通过移除空行和注释来压缩 JavaScript 代码

    1. [代码]JavaScriptCompressor.java/** * This file is part of the Echo Web Application Framework (herei ...

随机推荐

  1. Pandas:从CSV中读取一个含有datetime类型的DataFrame、单项时间数据获取

    前言 有一个CSV文件test.csv,其中有一列是datetime类型,其他列是数值列,就像下边这样: 问题 1.读取该CSV文件,把datetime列转换为datetime类型,并将它设置为索引列 ...

  2. SQL Server用SPLIT函数分割字符串

      declare @str varchar(100),@sql varchar(1000)set @str='1,2,3,4,5,6,7,8,9,10'set @sql='select Value= ...

  3. Python第二

    今日内容概要 基本运算符 流程控制 字符编码 理论特别多.结论特别少 文件处理 今日内容详细 基本运算符 1.算数运算符 x = 1 y = 5 res = x + y #加 res1 = x - y ...

  4. git flow 工作流程以及常用命令

    一.分支介绍 master 也是产品分支,只有一个,一般情况下不会在这个分支上进行代码操作 develop 只有一个,新特性的开发是基于 develop 开发的,但是不能直接在 develop 上进行 ...

  5. pandas常用操作详解(复制别人的)——数据透视表操作:pivot_table()

    原文链接:https://www.cnblogs.com/Yanjy-OnlyOne/p/11195621.html 一文看懂pandas的透视表pivot_table 一.概述 1.1 什么是透视表 ...

  6. ArcMap操作随记(4)

    1.统计各省份公路长度 [标识]→[汇总]→[视图][创建] 2.用户登录分配 [创建渔网]→[连接] 3.城市超市影响范围 [创建泰森多边形]→[标识]→[汇总] 4.三维可视化分析 [构造视线]→ ...

  7. 谈谈 Kubernetes Operator

    简介 你可能听过Kubernetes中Operator的概念,Operator可以帮助我们扩展Kubernetes功能,包括管理任何有状态应用程序.我们看到了它被用于有状态基础设施应用程序的许多可能性 ...

  8. web服务器-Nginx下载限速

    web服务器-Nginx下载限速 一. 限速介绍 在生产环境中,为了保护WEB服务器的安全,我们都会对用户的访问做出一些限制,保证服务器的安全及资源的合理分配. 限流(rate limiting)是N ...

  9. 基于WebSocket的简易聊天室

    用的是Flash + WebSocket 哦~ Flask 之 WebSocket 一.项目结构: 二.导入模块 pip3 install gevent-websocket 三.先来看一个一对一聊天的 ...

  10. [应用软件] VMware Workstation 12.0.0 Pro 正式版下载【附注册机+注册码】

    软件信息 软件名称: VMware Workstation 软件版本: 12 软件大小: 300 MB 软件语言: 简体中文 更新时间: - 软件授权: 免费 软件类别: 安装版 运行环境: WinX ...