Quick guide to Google closure compiler tool

Google’s closure compiler is an impressive tool that parses JavaScript code and make various optimizations on it, including minimizing its size.

This post will provide what is needed to effectively utilize it in minimum time.

Step 1 – verify consistant property access methods in your code ∞

The first thing you should do is make sure you have a consistent way of accessing object properties in your code – i.e don’t have one place in the code setting a property of some object, for example like this:

obj["hello"]="there"

or

return { "hello":"there" }

while in another place in your code you access it via the dot notation, e.g:

myobj = obj.hello

The reason this will cause problems is because the closure compiler will not rename strings but will rename the access fields in the dotted notation – which will of course cause problems in this case.

Step 2 – list the files that can be clumped together in one compilation ∞

The more files that can be compiled together with Google Closure compiler, the less you will have to deal with defining external functions and variables (i.e, those that are used by the compiled code but are defined in external/uncompiled code) or exporting variables and functions (those that you don’t want the compiler to rename since they are used by external/non-compiled code.

Step 3 – list internal functions and variables that non-compiled code needs to access ∞

Go through your code and list the functions and variables that you don’t want to be renamed by the Closure compiler since they have to be accessed by Javascript code that will not be compiled (You also need this if you have strings in the compiled code that are evaluated at runtime as function calls since strings are not changed by the compiler).

So, for example, say you have the following in the code you want to compile:

document.mydiv.innerHTML="<a href='#' onClick='myFunc1()'>Click</a>";
function myFunc1()
{
    alert("link was clicked");
}

function myFunc2()
{
    alert( "my API function was called" );
}

You will need to export MyFunc1 (because it is called from within a string) and MyFunc2 (because it is called from outside the compiled code).

The way to export functions so that they can be accessed after they are renamed by the compiler is to do the following trick – just add to your code:

window["myFunc1"]=myFunc1;
window["myFunc2"]=myFunc2;
window["myObj"]={};
window["myObj"][myMethod"] = myObj.myMethod;

This way, the compiler will rename myFunc1 and myFunc2 in the optimized code (and also myObj.myMethod), but the outside code will still be able to access them by their original name.

Step 4 – list external functions and variables that compiled code needs to access ∞

You need to let the closure compiler know which function calls and variables should not be renamed since the original name is needed to be able to call the external function/variable.
For example if you need to access an external variable named g_mymap and an external function named myinit then create a file named externs1.js for example which contains the following:

var g_mymap;
function init( str ) {}

Step5 – Compile! ∞

java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS  
                       --js=../src/script1.js 
                       --js=../src/script2.js 
                       --js=../src/script3.js 
                       --js=../src/script4.js 
                       --externs ../src/externs1.js 
                       --js_output_file=../release/code.js

Note that in the above example script1.js to script4.js are the scripts who’s variables and functions will be renamed in the optimization process, externs1.js contains the list of external functions and variables that you wish to access from within the compiled code (and thus you don’t want to be renamed – see step 4) and code.js will be the minimized and optimized code produced by the Google Closure compiler.

More progress on JavaScript Scrabble

I’m excited at the speed of the computer’s moves. Almost all moves take less than a second on my MacBook Air (1.86 GHz Intel Core 2 Duo) – the times when a move requires about 3 seconds is when the computer analyses how to play a joker. Did I already mention this is pure JavaScript running on the browser ?

Its amazing how far JavaScript has come, from being considered a toy language for running some checks on form inputs to being recognized as the powerful (though sometimes quirky) language that powers the Internet today.

New features
New features

Fastest Scrabble Algorithm ?

After making a small change, I’ve managed to improve the algorithm so that the computer will make a move in under a second every turn. Considering this is all written in pure JavaScript and runs on the browser, I’m starting to wonder whether the algorithm I wrote is the fastest existing scrabble algorithm out there…

JavaScript Scrabble in Russian

The nice thing about having a blog site that no one knows about is that if you’re creating a project and you don’t want potential competitors to know what you are up to, you can freely shout all your new ideas and features to the void… 🙂

The English JavaScript is working nicely so I’ve added a Russian version too, just to see how fast I can add support for other languages. The answer: very fast. It will take less than an hour to add localization and play support for any new language (RTL excluded for now, but will be handled later).

An example below:

Support for Russian
Support for Russian

Another sleepless night

Making progress with the Scrabble clone. Also made changes so it will even work on IE6. There is still the 10% of polishing work that takes 90% of the time, but its fun so I’m not complaining. Its great to see that the number of words in the dictionary have no noticeable effect on the speed of the search.

Current look - still under construction
Current look – still under construction

Scrabble in pure JavaScript

It took me almost two weeks but I’m nearing completion of an implementation of a fast Scrabble game against the computer written in pure JavaScript. It is both fast (less than 3 seconds per move) and unbeatable.

Here you can see the browser (playing in Red) giving me a humility lesson (playing in Green)…

First Scrabble prototype
First Scrabble prototype

Javascript Optimizing for Speed

I’m in the process of developing a CPU intensive Javascript game. I found the profilers of the different browsers lacking and needed some higher resolution probing of CPU hogger sections in the code. To this effect I created the timers manager below. Basically at any point in the code where you want to start measuring something, say data sorting, you add the line g_timers.begin("my data sort"); and at the end of where the code does its thing you add the line g_timers.pause("my data sort");. You can add as many checkpoints as you see fit for different part of the code – just make sure the string timer identifier passed to the g_timers.begin method is identical to the one passed to the corresponding g_timers.pause method.

Finally, whenever you want to see a report of the accumulated times of all the timers you’ve planted, simply call g_timers.show(). You might probably also want to call g_timers.reset() after that to zero all the accumulated time measurements.

var timers = {};
timers.new = function()
{
    var self = {}
    var t1,total;

    self.begin = function(id) {
        t1[id] = +new Date();
        if (!(id in total))
            total[id] = 0;
    }

    self.pause = function(id) {
        if (id in t1) {
            var t2 = +new Date();
            total[id] += t2-t1[id];
            t1[id] = t2;
        }
    }

    self.show = function() {
        console.log( "Total times:")
        for (id in total)
            console.log( id+": "+total[id]+" ms." );
    }

    self.reset = function() {
        t1    = {};
        total = {};
    }

    self.reset();
    return self;
}

var g_timers = timers.new();

I think IE6 does not like the above method of creating the JavaScript object – if you have problems, just use your own flavor.

JavaScript Graphic Libraries

I’ve been looking at some JavaScript libraries to be used for data visualization – there are quite a few, from impressive heavy duty data visualization frameworks like D3 (which requires modern browsers that support SVG) through powerful vector rendering libraries like Raphaël that work across almost all browsers and versions using SVG or VML for older versions of IE.

The following is a sample from yet another library (JSDraw2DX) that works on both IE and non-IE browsers. View frame source to see the simplicity with which these libraries can create useful presentations (click and drag the yellow dots).

Linux and HP printers/scanners

While attempting to scan a document with my newly purchased HP Deskjet 3070 All-in-One Printer B611b from my Ubuntu 12.04 desktop I learned three things:

  • There’s an excellent scanning software for Linux called XSane
  • Ubuntu 12.04 comes with the drivers for most HP printers already built in, so there was nothing else needed other then launcing XSane and scanning the document
  • hplipopensource.com contains the latest HP drivers for Linux just in case you don’t have the relevant driver for you printer pre-installed. The site even has a wizard which will guide you through to the driver you need to download and how to install it so your Linux can see your printer (I learned this from here)

Combination Algorithms and the Natural Logarithm Base

While comparing the efficiency of my iterative method for generating combinations vs. the recursive method shown at the Rosetta Code site I picked up on a pattern that at first glance is not obvious so I’m still looking into it. It seems that the ratio of the efficiency between the algorithms seems to approach the natural logarithm base (2.71828182…)

Here’s the code – I’ll do some more research before attempting to explain what is going on here

------------------------------------------------------------------------------
-- Lua recursive code for generating combinations from Rosetta Code
function map(f, a, ...)
    c1=c1+1
    if a then return f(a), map(f, ...) end
end

function incr(k)
    return function(a) return k > a and a or a+1 end
end

function combs1(m, n)
    if m * n == 0 then return {{}} end
    local ret, old = {}, combs1(m-1, n-1)
    for i = 1, n do
        for k, v in ipairs(old) do
            ret[#ret+1] = {i, map(incr(i), unpack(v))}
        end
    end
    return ret
end

--for k, v in ipairs(combs(3, 5)) do print(unpack(v)) end

-----------------------------------------------------------------------------
-- My Lua iterative code for generating combinations
-- input a, b (a number of slots, b number of symbols)
function combs2(a,b)
    if a==0 then return end
    local taken = {}
    local slots = {}
    for i=1,a do slots[i]=0 end
    for i=1,b do taken[i]=false end
    local index = 1
    while index > 0 do repeat

        repeat
            c2=c2+1
            slots[index] = slots[index] + 1
        until slots[index] > b or not taken[slots[index]]

        if slots[index] > b then
            slots[index] = 0
            index = index - 1
            if index > 0 then
                taken[slots[index]] = false
            end
            break
        else
            taken[slots[index]] = true
        end

        if index == a then
            -- for i=1,a do
            --     io.write( slots[i] )
            --     io.write( " " )
            -- end
            -- io.write( "n")
            taken[slots[index]] = false
            break
        end

        index = index + 1
    until true end
end

------------------------------------------------------
-- A comparison of the number of operations required
-- by recursive and non-recursive method. Tests show
-- that as the number of slots and symbols rise, the
-- ratio of the efficiency shows an interesting pattern
-- and has to do with the base of the natural logarithm
-------------------------------------------------------

function compare(sl,sy)
    c1=0
    c2=0
    combs1(sl, sy)
    combs2(sl, sy)
    print( "slots:"..sl..", symbols:"..sy.." => iterative/recursive ratio:"..c2/c1)
end

for n=2,11 do
    compare(n,n)
end