Table of Contents
Introduction
Web developers have been told for years that they must optimize their code for production environments. The conventional wisdom holds that by compressing all of the JavaScript an application requires, bandwidth usage will be reduced and applications will load much faster—a process Sencha has helped to automate for years through Sencha Cmd.
However, you may not realize, as many of our customers do, that you can get even more performance out of this process by adjusting how Sencha Cmd compresses your code. Although Sencha Cmd uses YUI Compressor by default, you can configure your build output to use Google Closure or UglifyJS instead – and, as we’ll see in a moment, it often pays to test which compression tool offers the best savings.
The Javascript Web Framework tool automates many tasks related to the Sencha Ext JS app development lifecycles, with an ever-expanding list of command-line options ranging from code generation to native packaging. The tool also includes Ant integration and a comprehensive set of command-line syntax. It can be seamlessly integrated into your enterprise build environments or used as a standalone tool to increase developer productivity and application performance.
Please note that this post should not be viewed as a recommendation for any specific tool. Many factors could influence your decision to choose one compression tool over another, and this post will attempt to provide some approaches to consider when making your own decision.
Why Would You Want to Change the Default Settings?
While the mechanics involved can be quite complicated, the general idea behind JavaScript compressors is rather simple: your code is tokenized and parsed into an abstract syntax tree (AST), then regenerated into a JavaScript program with modifications to compress the output.

The specifics of how these individual tools work (e.g. the algorithms used, etc) is beyond the scope of this article, but let’s quickly examine YUI Compressor, Closure and UglifyJS at a high level.
YUI Compressor
YUI Compressor is a command-line utility written in Java. It can perform both JavaScript and CSS compression, making it an ideal tool for most projects. YUI Compressor has been deprecated, although it still remains very popular.
As previously noted, Sencha Cmd uses YUI Compressor by default in the application build process.
Google Closure Compiler
Google Closure Compiler is also built with Java, but only performs JavaScript compression (no CSS). Closure can be run directly from the command-line, contains additional services (UI, API) and offers greater control over the compression process through code annotations and compilation flags.
UglifyJS
UglifyJS is the only one of these tools written with JavaScript, making it ideal for use in Node.js environments. Like Closure, UglifyJS only offers JavaScript compression (no CSS). UglifyJS is run as a command-line utility and allows detailed control over the compression process through a number of compilation flags.
Note: Sencha Cmd is built with Java, so UglifyJS is run using Rhino rather than Node.js.
Keep in mind that because each tool will produce slightly different compression output, it is hard to predict which will yield the most optimal results. To help illustrate this point, let’s dive into a sample application and test how each of these compression tools handles the code.
Case Study: Ext JS 5 Sample App
The easiest possible way to illustrate this concept is to generate a sample application using Sencha Cmd:
sencha -sdk ~/path/to/ext generate app Foo ./foo
Because Sencha Cmd scaffolds a fully-functioning sample application, we don’t need to do anything else. Running the app in Firefox, our “development” app loads with the following stats:

There isn’t much of a surprise here. An Ext JS application in “development” mode relies on the Ext.Loader to synchronously load each JavaScript dependency — and although 0.29s isn’t much time spent waiting for 24 HTTP requests, it is easy to imagine how much longer an enterprise application might take.
After running sencha app build
to get our sample app into “production”, the network statistics have changed quite a bit:

Clearly we have fewer JavaScript resources, and the overall load time has dropped to 0.02s! This is all thanks to the magic of JavaScript compression.
Obviously the use of JavaScript compression is important — but is it possible that tweaking the Sencha Cmd settings might yield even better results? To change which compression tool Sencha Cmd uses, let’s edit the app.json file:
{ //... /** * override objects for setting build environment specific * settings. */ "production": { "compressor" : { //"type" : "yui" //the default... //"type" : "uglify" //or... "type" : "closure" } }, //... }
Now if we run sencha app build
, the build process will use the configured compression tool. Next, let’s look at the results of using the various compression tools on our sample application:
Compressor | File Size (Bytes) | % of Original |
(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% |
In the table above, you can see the actual results of the compressed file sizes, in addition to a second step of gzipping the compressed output files (run via the gzip
terminal command with default settings). It is interesting to note that while UglifyJS yielded the smallest output after our build process, Closure actually wins when we consider additional gzip compression.


It’s possible that we might have achieved even better results if we tweaked the gzip settings involved.
Considerations
So Closure wins… we should all just start using Closure. Right? Sadly it’s not so clear-cut.
If we take the additional step to measure the total time involved to run our build process (including generating our CSS theme and other steps), we will notice something important.
The sample app uses Ext JS 5.0.1.1255, and I ran the commands using Sencha Cmd 5.1.0.26 on my MacBook Pro (early 2011, OSX 10.10.1, 2GHz Intel i7, 8GB RAM). Results may vary on your machine. Note: I also modified the build settings to avoid theme slicing for older browsers.
sencha -ti app build -c
The command above will provide us with the total time of execution (-ti flag), and it will also remove previous build output (-c flag) to guarantee our comparisons are clean. Running a build with each of the compression tools, we start to see why YUI Compressor is the default choice:
- YUI: 0:00:33
- Closure: 0:00:54
- UglifyJS: 0:15:40
Closure takes nearly double the time to compress our build output—and UglifyJS takes roughly 31x longer! The takeaway here is that it’s worth deciding whether or not the significant increase in build time is worth a few saved kilobytes.
Ultimately, some companies may view a few kBs as insignificant when their primary objective is simply reducing the size of their JavaScript assets. But high-traffic applications will likely cause them to pay close attention to these minute details — where page speed and overall bandwidth can dramatically affect profits.
Finally, you might ask if any of the compressed JavaScript executed faster after compression. It’s nearly impossible to tell, and existing JSPerf tests indicate virtually no difference in speed of execution.
Customizing JS Compression
Sencha Cmd doesn’t currently allow us to configure the settings for YUI Compressor, but then again YUI Compressor doesn’t offer many settings to configure. Sencha Cmd does allow us to configure how Closure compiles our source code.
Opening app.json
again, we can configure the Closure compilation options directly on the “compressor” object:
{ //... "production": { "compressor" : { "type" : "closure", //all other keys are passed as options "ambiguateProperties" : true, "foldConstants" : true } }, //... }
Sencha Cmd has not yet implemented the custom configurations for UglifyJS, but that feature is on the roadmap.
Conclusion
Compressing your JavaScript is a well-established best practice for increasing the performance of a web application. Sencha Cmd automates this process by default, but it may be worth playing with the advanced settings to squeeze additional optimizations out of your production build.
While this is a very insightful post, the gains involved seem so marginal they’re not worth the effort. Looks like less than half of a single percent savings with gzipped Closure. If you have a 3 MB app, that’s 3000*0.004 = ~12 KB of savings. Not sure if that’s worth much in this day and age ;)
In the chrome inspector tab network for https://manage.space.sencha.com/#login I get :
28 request | 933K tranferred | finish 9.77s | DOMContentLoaded: 483 ms | Load 8.12s
and this is a basic page with a form with 3 input, almost 1mb the same page is build with bootstrap and jquery could be have 100k, so all time using compression Extjs size(kb) = (jquery + bootstrap)x 10
regards
Frank
Thanks for the post…interesting reading about the gzip stuff. I know you can set this stuff in your server settings, but how do you set this stuff when testing on localhost? I added this stuff to me httpd.conf file:
Compressed javascript files
AddEncoding x-gzip .jgz
AddType application/x-javascript .jgz
# Compressed css files
AddEncoding x-gzip .cgz
AddType text/css .cgz
But I still get ‘Uncaught SyntaxError: Unexpected token ILLEGAL’ error on the gzipped file (after changing the link in app.json from app.js to app.js.gzip in a production mode test).
Any ideas? Or am I best testing this on my actual server? I’d like to compress the files manually myself first.
Thanks
@Ivan – as I said in my post, it’s totally up to you to decide. Amazon and Google would likely disagree that a fraction of a percent isn’t “worth the effort” because milliseconds of load time are literally worth billions of dollars to them. Then again we don’t work for those companies :-)
@Frank – The page you reference is one view inside a much larger single-page-application.
@TylarDurdan – It is definitely better to set this on the server. I don’t know why you’d be hitting those errors locally, could be any number of reasons in theory.
Worth noting too that the two non-YUI methods support the generation of source maps, which can be handy for debugging production code.
Then again, we’ve never got around to switching, but I hope to at some point!
Ah, just tried it though and there is no way of passing –create_source_map to the closure compiler.
Found a workaround here (https://www.sencha.com/forum/showthread.php?269033-How-to-generate-JS-source-map&p=1090615&viewfull=1#post1090615), but it’s not ideal.
@Westy Sourcemaps are a dead end anyway for production Touch (and soon ExtJS) apps. Browsers don’t return a callstack for eval’d code. Since the microloader implementation evals non-remote scripts from localstorage, that leaves you with just the error message itself. It’s been my experience that 9 times out of 10 the error manifests itself in the framework code so, w/out the callstack, you’re left with almost no info to go off of (w/ sourcemap or not). TrackJS is the only viable solution right now IMO. Thoughts?
Why did you start using “effra” font in your blog? It looks just terrible on LCD screen.
I am just wondering, when using closure compiler, it is written that it only performs JavaScript compression (no CSS). So does this means that sencha cmd will not compress the CSS or there will be CSS compression but using different compression method?
Do I need to do something special when I call sencha cmd to build for production?
The CSS compressor is independent of using YUI or Closure, these two only are used for javascript compression. To build your app, use sencha app build production . If you need additional build customizations, please look at this Cmd guide for reference
http://docs.sencha.com/cmd/6.x/advanced_cmd/cmd_build.html
Is this still the case with Sencha Cmd 6.5.3.x?
I have the production block setup in my app.json with the compressor set to yui but I still see
Processing data with CmdJavascriptCompressor
in the build console output