Writing Compressible JavaScript

June 19, 2010 by Ed Spencer · 8 Comments 

Writing a library is a balancing act between the (sometimes competing) interests of API clarity, code clarity, performance and compressibility. In this article I’m going to detail three of the approaches we take to meet this balance and suggest them for your own usage.

1. Collecting var statements

Every time we declare variables we add 4 bytes to the compressed file size. Variables are declared sufficiently often that this can really add up, so instead of this:

var myFirstVar = 'something';
var myOtherVar = 'another thing';
var answer = 42;
var adama = true;

One should use this form:

var myFirstVar = 'something',
    myOtherVar = 'another thing',
    answer = 42,
    adama = true;

When this code is compressed, each variable name above is turned into a single-letter name, meaning that the wasted 4 bytes per useless additional ‘var ‘ in the first example would have contributed significantly to code size with no benefit.

2. Local variable pointers to object properties

The following code (pruned from a previous version of Ext JS) is not as compressible as it could be:

var cs = {};
for (var n in this.modified) {
    if (this.modified.hasOwnProperty(n)) {
        cs[n] = this.data[n];
    }
}
return cs;

We’re better off aliasing ‘this.modified’ to a local variable first. Aside from the performance benefits some JS engines derive from not having to perform object property lookups over and over again, we save precious bytes this way too:

var modified = this.modified,
    changes  = {},
    field; 

for (field in modified) {
    if (modified.hasOwnProperty(field)) {
        changes[field] = this.data[field];
    }
}

return changes;

Again, the minifier will compress those variable names down to a single character each, so for our ‘this.modified’ example we’re going to use 15 bytes to define the variable plus 1 byte each time we use it (totalling 15), vs the 26 bytes for that code previously. This approach scales especially well – were we to refer to this.modified a third time in the function, as our code will now minify to 16 bytes, vs 39 without the variable declaration.

Side note: in the first example here the variable ‘n’ was being used in the for…in loop. We can always safely exchange that for a meaningful variable name (in this case ‘field’) and leave the rest to the minifier.

3. Aliasing ‘this’ to ‘me’

In Ext.data.Record’s markDirty method we have the following code:

this.dirty = true;
if(!this.modified){
    this.modified = {};
}
this.fields.each(function(f) {
    this.modified[f.name] = this.data[f.name];
},this);

There are 7 references to ‘this’ in that method, taking 28 bytes and completely incompressible. We could rewrite it like this (note that the final ‘this’ can be removed in this format):

var me = this; 

me.dirty = true;
if (!me.modified) {
    me.modified = {};
}
me.fields.each(function(f) {
    me.modified[f.name] = me.data[f.name];
});

Again, our minifier will change the ‘me’ var to a single character, saving us 8 bytes in this instance. That might not sound like a lot but after minification it equates to a 7% reduction in code size for this function.

In each of the cases above we’re generally talking about single-digit percentage savings after minification. There is value in that small slice though, especially as more and more applications shift onto bandwidth-constrained mobile platforms.

The first two approaches are no-brainers and must always be done but the third is slightly more controversial. Personally I find it makes the code a little harder to read, largely because my syntax highlighter doesn’t recognise that ‘me’ is now the same as ‘this’. Its value also varies significantly by function – some functions can contain over a dozen references to ‘this’, in which case this approach makes a big difference.

Random Posts

About Ed Spencer
Software Architect at Sencha Inc where I lead the development of Ext JS and supporting projects. A longtime lover of JavaScript and related geekery, currently living in Palo Alto.

Comments

8 Responses to “Writing Compressible JavaScript”
  1. Lloyd K says:

    Hi Ed!

    Nice article as always, however surely since most web servers now supply said JavaScript files compressed under gzip or deflate such savings are marginal at best?

  2. Arthur Kay says:

    Awesome post Ed! I never really gave much thought to compressing var statements but your analysis is spot-on. Thank you for posting this!

  3. Ed Spencer says:

    @Lloyd that’s definitely true in most cases, but applying these techniques provides a good fallback for when gzip is not enabled (which does happen surprisingly often). For the most part it wouldn’t be worth going through the entire library and updating it with this techniques but it makes sense to do so for new or refactored code.

    @Arthur thanks, I’ll try to remember to blog more often now that Sencha Touch is public

  4. Rene Saarsoo says:

    The collecting of var statements is clearly something that the compression tool should do for you. Even if the compression tool doesn’t support it by itself, it’s relatively easy to write a preprocessor that converts your var statements from one form to another before passing on to the compression tool.

    The other two approaches could IMHO also be automated, at least to some extent. Although as easily as with the var statements.

  5. Rene Saarsoo says:

    Wanted to write: Although NOT as easily as with the var statements.

  6. F_D says:

    Collecting the var statements is a path potentially fraught with peril if you are not careful and disciplined (also: …if your collaborators are not also careful and disciplined). Miss one comma and you’ve accidentally moved a sub-set of your variables into the global scope. (A potentially nightmarish debugging session, for sure–especially in a large codebase.) Not that there are not benefits to this pattern (it is one that I use myself)–but also a good idea to consider the risks.

  7. Brent says:

    Super killer advice, thanks !!

Trackbacks

Check out what others are saying about this post...
  1. [...] This post was mentioned on Twitter by Nils Dehl and Edward Spencer, ignar. ignar said: Writing Compressible JavaScript http://ff.im/-mnWDI [...]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!