概述

这么多年来,Web开发人员都被告知应优化他们生产环境的代码。传统的方法是将应用程序的所有脚步进行压缩以减少应用程序的大小,以便让应用程序加载更快。而Sencha Cmd这么多年以来已经将这个过程自动化了。

然而,许多客户,还不知道可通过调整Sencha Cmd的压缩代码来进行一些额外的处理。尽管Sencha Cmd默认是适应YUI压缩来进行压缩的,但还可以通过配置使用Google Closure或UglifyJS来进行压缩。下面将会介绍这些,并去测试哪一个压缩工具提供了最大的压缩效果。

要注意的是,本文的本意并不是让你使用某个特定的工具,至于选择哪一种,不选择哪一种,是有许多的因素决定的,本文只是尝试提供一些参考意见。

为什么要修改默认设置?

虽然脚本压缩的处理机制相当复杂,但总的来说还是相当简单的:代码会被标记后解析为一个抽象语法树(abstract syntax tree,AST),然后通过脚本程序进行修改并压缩后输出。

虽然这些独立的工具是如何工作的(如使用什么算法等)已经超出了本文的范围,但还是让我们在更高的层级上来快速体验一下YUI压缩、Closure和UglifyJS。

YUI压缩

YUI压缩是一个使用JAVA编写的命令行工具,它既可以处理Javascript,也可以处理CSS压缩,对于大多数项目来说,它是一个理想的工具。YUI压缩虽然很受欢迎,但已经不再更新了。

如前文所述,Sencha Cmd默认是使用YUI压缩来处理应用程序的生成过程的。

Google Closure编译器

Google Closure编译器也是使用JAVA创建的,不过它只能处理javascript压缩(不包含CSS)。Closure可以直接从命令行运行,它还包含其他的一些服务(UI和API),并通过代码注释和编译标志为压缩处理提供了更多的控制权。

UglifyJS

UglifyJS是这些工具中唯一使用javascript编写的工具,因此非常适合应用于Node.js环境中。如Closure一样,UglifyJS只提供javascript压缩(不包括CSS)。UglifyJS是以命令行工具方式运行的,并允许通过大量的编译标志来精细的控制压缩过程。

注意:Sencha Cmd是使用JAVA创建的,而UglifyJS的运行需要使用到Rhino,而不是Node.js。

要记住的是,因为每一个工具会产生不同的压缩输出,因而很难预测哪一个是最理想的结果。为了说明这一点,下面将通过一个示例应用程序来测试这些压缩工具如何去处理这些代码。

案例研究:Ext JS 6示例应用程序

最简单的用来说明这一概念的方式就是使用Sencha Cmd来生产一个示例应用程序:

sencha -sdk ~/path/to/ext generate app Foo ./foo

因为Sencha Cmd自身能搭建一个完整的示例应用程序,因而我们不需要做任何事情。在Firefox打开应用程序,在“开发”模式中应用程序的加载数据统计如下:

这里没有太多惊喜,在“开发”模式中的Ext JS 应用程序依赖于Ext.Loader来同步加载每一个Javascript依赖,虽然只花费了0.29秒来等待24个HTTP请求,但可以想象得出一个企业应用程序可能需要花费更多的时间。

在运行”sencha app build”将示例应用程序转为“生产”模式后,网络统计已经有所改变了:

很显然,现在只加载了很小的脚本资源,而整体的加载时间已经降至0.02秒了。这一切都得感谢javascript压缩的魔力。

显然,使用javascript压缩是很重要的,不过,通过调整Sencha Cmd的设置可以获得更好的结果吗?如果要修改Sencha Cmd所使用的压缩工具,可编辑app.json文件:

    {
//... /**
* override objects for setting build environment specific
* settings.
*/
"production": {
"compressor" : {
//"type" : "yui" //the default...
//"type" : "uglify" //or...
"type" : "closure"
}
}, //...
}

现在运行“sencha app build”,将会使用配置的压缩工具。接下来,让我们来看看使用不同压缩工具后的示例应用程序是如何的:

压缩工具 文件大小(字节) 与源文件比较(%)
(none) 5,166,339 100.0%
YUI 1,109,534 21.48%
Closure 1,081,242 20.93%
UglifyJS 1,069,126 20.69%
YUI (gzip) 343,696 6.65%
Closure (gzip) 323,615 6.26%
UglifyJS (gzip) 329,182 6.37%

在以上表格中,可以看到压缩文件的大小,另外一部分是使用gzip压缩后的输出文件(通过gzip终端命令使用默认设置的运行结果)。从结果可以看到,使用UglifyJS可以输出最小的文件,而如果考虑gzip压缩,则Closure更佳。

如果调整gzip的设置,可能会获得更好的结果。

注意事项

由于Closure赢了,我们是否只是有Closure呢?可悲的是,其实并不是那么明确的。

如果采用额外的步骤来衡量所生产应用程序过程的总时间(包括生产CSS主题和其他步骤),就会注意到一些重要的事情。

示例应用程序使用的是Ext JS 5.0.1.1255,是在MacBook Pro(2011年初,OSX 10.10.1, 2GHz Intel i7, 8GB RAM)上使用Sencha Cmd 5.1.0.26进行压缩的。如果在你的机器上可能会有不同的结果。要注意的是,我修改过生成设置,以避免主题为旧的浏览器进行切片.

 sencha -ti app build -c

以上命令会为我们提供执行的总时间(-ti 标志),b并会删除之前生成的输出(-c 标志)以保证压缩是一个干净压缩。为每一个压缩工具运行一次生产,就可以看到为什么YUI压缩是默认选择了:

  • YUI: 0:00:33
  • Closure: 0:00:54
  • UglifyJS: 0:15:40

Closure花费了近两倍的时间去压缩生成的输出,而UglifyJS则需要31x这么长的时间!这里要点就是,是否值得为几千字节的问题而花费大量增加的生产时间。

归根结底,一些公司的首要目标只是减少javascript的大小,而并注重哪几千字节。不过,对于高流量应用程序,则会让他们更关注这些微小的细节,因为页面的速度和总体带宽可能会大大影响利润。

最后,你可能会问任何压缩过的javascript代码执行上是否会更快。这几乎是不可能的事,现有的JSPerf测试表明,执行速度几乎是没有任何差别的。

自定义JS压缩

Sencha Cmd目前还不允许去配置YUI压缩的配置,不过YUI本身也没有提供更多的配置。Sencha Cmd目前允许用户配置Closure去如何压缩代码。

再次打开app.json,在文件中科直接通过“compressor”对象来配置Closure的压缩选项:

{
//... "production": {
"compressor" : {
"type" : "closure", //all other keys are passed as options
"ambiguateProperties" : true,
"foldConstants" : true
}
}, //...
}

Sencha Cmd目前还没有实现UglifyJS的自定义配置,不过该功能已包含在路线图中。

小结

压缩javascript是既定的提高Web应用程序性能的最佳做法。Sencha Cmd默认情况下会自动进行处理,不过,使用更先进的设置来对生成的产品进行额外的优化,是值得的。

**作者: Arthur Kay

Arthur Kay is a Senior Software Engineer at Sencha. He studied Music and Computer Science at Loyola University Chicago and has been involved with the Web since the late 1990s.**

【翻译】Sencha Cmd中脚本压缩方法之比较的更多相关文章

  1. ExtJS6的中sencha cmd中自动创建案例项目代码分析

    在之前的博文中,我们按照sencha cmd的指点,在自己win7虚拟机上创建了一个案例项目,相当于创建了一个固定格式的文档目录结构,然后里面自动创建了一系列js代码.这是使用sencha cmd自动 ...

  2. 使用Sencha Cmd创建脚本框架

    从Ext JS 4.1.1a 开始,为了配合 Sencha Touch开发  而设计了 Sencha Cmd这个跨平台的命令行工具. 要使用Sencha Cmd,必须先安装好 Java Run-tim ...

  3. 【翻译】在Sencha Touch中创建离线/在线代理

    原文:Creating an Online/Offline proxy in Sencha Touch 概述 在Sencha Touch中,一个常见的需求就是,当设备在没有连接互联网的时候,应用程序必 ...

  4. 【翻译】使用新的Sencha Cmd 4命令app watch

    原文:http://www.sencha.com/blog/using-the-new-app-watch-command-in-sencha-cmd-4/ 作者:Don Griffin Don Gr ...

  5. 在CMD中使用for命令对单行字符串做分割的方法

    我们都知道CMD中的for命令是执行循环命令的,数据来源可以是一个文件,一个命令的结果或一个字符串,只有这3种来源 如果是一个文件则对这个文件的所有字符串进行循环处理 如果是一个命令结果,那么对这个命 ...

  6. Django 资源 与 知识 Django中自建脚本并使用Django环境 model中的save()方法说明 filter()用法

    Django 资源 与 知识 Django中自建脚本并使用Django环境 model中的save()方法说明 filter()用法 2018/11/06 Chenxin 资料说明 Django基础入 ...

  7. 在html中添加script脚本的方法和注意事项

    在html中添加script脚本有两种方法,直接将javascript代码添加到html中与添加外部js文件,这两种方法都比较常用,大家可以根据自己需要自由选择 在html中添加<script& ...

  8. shell中引用其他脚本的方法

    在Shell中引用其他脚本的方法是source   filename.sh 或    .    filename.sh 注意:      .   和   filename.sh之间必须有空格

  9. PowerShell因为在此系统中禁止执行脚本解决方法

    PowerShell因为在此系统中禁止执行脚本解决方法   在Powershell直接脚本时会出现: 无法加载文件 ******.ps1,因为在此系统中禁止执行脚本.有关详细信息,请参阅 " ...

随机推荐

  1. JAVA GC垃圾收集器的分析

    本篇文章主要介绍了"JAVA GC垃圾收集器的分析",主要涉及到JAVA GC垃圾收集器的分析方面的内容,对于JAVA GC垃圾收集器的分析感兴趣的同学可以参考一下.       ...

  2. Mysql根据一个基库生成其他库与其不同的库升级脚本

    今天研究了一下不同数据库之间如何做同步.弄了一个升级工具类,希望以后还能有所帮助. public class UpgradeDataBase { public static void main(Str ...

  3. 75. Sort Colors(中等)

    Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...

  4. Servlet 执行流程 生命周期 ServletConfig 线程安全

    Day34 servlet 三.如何使用Servlet 1.继承GenericServlet类(通用) (1)GenericServlet类有一个关键的设计,定义了一个私有的ServletConfig ...

  5. jQuery 遍历 – 后代

    后代是子.孙.曾孙等等. 通过 jQuery,您能够向下遍历 DOM 树,以查找元素的后代. 向下遍历 DOM 树 下面是两个用于向下遍历 DOM 树的 jQuery 方法: children() f ...

  6. MacOS下安装rvm的几点注意

    如果用以下链接无法下载的话: curl -sSL https://get.rvm.io | bash -s stable #或者 curl -L https://rvm.io | bash -s st ...

  7. jQuery中$(function()与(function($)等的区别详细讲解

    (function($) {-})(jQuery); 这里实际上是匿名函数,如下: function(arg){-} 这就定义了一个匿名函数,参数为arg 而调用函数时,是在函数后面写上括号和实参的, ...

  8. 【SSH系列】hibernate映射 -- 一对一双向关联映射

    开篇前言 上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身 ...

  9. WebService案例入门(基础篇)

    [版权申明:本文系作者原创,转载请注明出处] 文章出处:http://blog.csdn.net/sdksdk0/article/details/52106690 作者:朱培 ID:sdksdk0 邮 ...

  10. iOS学习笔记--触摸事件

    最近空闲时间在学习iOS相关知识,几周没有更新文章了,今天总结下这些天的学习内容,也整理下iOS的学习笔记,以便以后查阅翻看- iOS中的事件可以分为3大类型: 触摸事件 加速计事件 远程控制事件 响 ...