使用Google Closure Compiler高级压缩Javascript代码注意的几个地方
介绍
GCC(Google Closure Compiler)是由谷歌发布的Js代码压缩编译工具。它可以做到分析Js的代码,移除不需要的代码(dead code),并且去重写它,最后再进行压缩。
三种压缩模式
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.js和b.js就会出问题,结果会是a.js中什么都没有,b.js中getName方法未定义(undefined)。正确的做法则是,两者合并再进行压缩。
结语
GCC的高级压缩(Advanced)非常强大,对代码压缩做到了极致,但是其对代码书写要求也比较严格,并且破坏性压缩也被很多开发者所诟病。
但是稍加注意,严格规范自身代码风格,了解GCC压缩方式原理,利用好GCC高级压缩,一定会大大减少JS的体积,从而大幅度的提升前端代码性能。
另外,GCC像其他压缩工具一样,也有Grunt、Gulp构建组件,可以很方便的去使用它。
//原文地址:http://segmentfault.com/blog/laopopo/1190000002575760
使用Google Closure Compiler高级压缩Javascript代码注意的几个地方的更多相关文章
- 使用Google Closure Compiler高级压缩Javascript代码
背景 前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件. 如今主流的Js代码压缩工具主要有: 1)Uglify http://lisperator.net/uglifyjs/ ...
- Google Closure Compiler高级压缩混淆Javascript代码
一.背景 前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件. 如今主流的Js代码压缩工具主要有: 1)Uglify http://lisperator.net/uglifyj ...
- 使用Google Closure Compiler全力压缩代码(转)
JavaScript压缩代码的重要性不言而喻,如今的压缩工具也有不少,例如YUI Compressor,Google Closure Compiler,以及现在比较红火的UglifyJS.Uglify ...
- Google Closure Compiler 高级模式及更多思考(转)
前言 Google Closure Compiler 是 Google Closure Tools 的一员,在 2009 年底被 Google 释出,早先,有 玉伯 的 Closure Compile ...
- JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
网上搜索了,目前主流的Js代码压缩工具主要有Uglify.YUI Compressor.Google Closure Compiler,简单试用了UglifyJS 和Google Closure Co ...
- bootstrap-datetimepicker在经过GC(Google Closure Compiler)压缩后无法使用的解决方案
将压缩级别由simple改成whitespace 问题就是这样之后压缩后的文件大了很多 <?xml version="1.0"?> <project name=& ...
- Gulp压缩JavaScript代码
因为gulp是自动化工具,所以我们得告诉它,需要怎么做,才能达到我们的目的. 我们首先得新建一个js文件,用来编写我们的需求,以便gulp能按着我们的意愿来执行. 我将这个js文件取名叫gulpfil ...
- Grunt 使用(二)uglify插件压缩javascript代码
本文在配置grunt基本环境的基础下,讲解如何使用grunt-contrib-uglify进行javascript压缩 本文只介绍了grunt-contrib-uglify插件的一种压缩方式适用于大部 ...
- 【Java】通过移除空行和注释来压缩 JavaScript 代码
1. [代码]JavaScriptCompressor.java/** * This file is part of the Echo Web Application Framework (herei ...
随机推荐
- Ubuntu下使用nvm
写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...
- .NET 4.6.2正式发布带来众多特性
虽然大多数人的注意力都集中在.NET Core上,但与原来的.NET Framework相关的工作还在继续..NET Framework 4.6.2正式版已于近日发布,其重点是安全和WinForms/ ...
- 使用webstorm+webpack构建简单入门级“HelloWorld”的应用&&引用jquery来实现alert
使用webstorm+webpack构建简单入门级"HelloWorld"的应用&&构建使用jquery来实现 1.首先你自己把webstorm安装完成. 请参考这 ...
- Python-Jenkins API使用 —— 在后端代码中操控Jenkins
最近在工作中需要用到在后台代码中触发Jenkins任务的构建,于是想到Jenkins是否有一些已经封装好的API类库提供,用于处理跟Jenkins相关的操作.下面就简单介绍下我的发现. Linux C ...
- 23种设计模式--建造者模式-Builder Pattern
一.建造模式的介绍 建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...
- so 问题来了,你现在值多少钱?
年底了一大帮人都写着年底总结,总结一年做过的事.错过的事和做错的事.增长了多少本事,找没找到女朋友……来年做好升职加薪,要么做跳槽的准备,程序猿又开始浮躁了……. so 问题来了,你现在值多少钱? 这 ...
- C# 自定义控件VS用户控件
1 自定义控件与用户控件区别 WinForm中, 用户控件(User Control):继承自 UserControl,主要用于开发 Container 控件,Container控件可以添加其他Con ...
- 6_Win7下Chrome主页被流氓网站hao123.com劫持后的解决方法。
今天安装了一个PDF阅读器,免费的,你懂的,结果自己安装的时候没有将默认的选项取消,就被hao123流氓网站劫持啦. 说实话某免费PDF阅读器还算好的,有一个可以供你选择的项.不想某些软件直接就默认选 ...
- Vim使用
模式 ESC\Ctrl+c:退出编辑模式 ZZ\wq:命令模式下保存退出 编辑 i:进入编辑模式 I:转到行首非空字符开始编辑 s:删除当前字符进入编辑模式 a:从当前字符后开始编辑 A:从当前行末非 ...
- js月份,日期加一天
js没有直接可以用的函数,所以只能自己写,其中需要涉及到每个月天数的判断,如果是2月份的话,还要涉及到闰年的判断 var addDate = { //日期,在原有日期基础上,增加days天数,默认增加 ...