Javascript minification in capistrano/webistrano

Photo: http://www.sxc.hu/photo/347930

Recently i had to automate the minification of specific javascripts. Since we don’t have a real build tool, i thought it was best to do this during deployment.
For (automatic) deployments our tool of choice is Webistrano, which is based on Capistrano, which is written in Ruby.

Capistrano has this concept of recipes, which are small scripts that you write to do specific tasks during deployment.
So, one of these tasks could be the minification of some javascript.

But for the minification and deployment of that, i was bound to some constraints:

  • We’re using the yuicompressor (java)
  • Deploy target machines do not have java installed
  • So we have to do the minification locally

After doing some initial research it was quite easy to do, and i came up with the following code:

The approach can be considered somewhat unusual, as the project’s files are first uploaded to the server. And after that the javascript is minified and uploaded seperately. This is mainly because I couldn’t find another hook within capistrano that fits my need.
Of course, you can rewrite this script to work with any other local command too.

Note/disclaimer: This script uses the copy_cache directive. I’m not a capistrano expert, but this variable might not be available to all deployment strategies. This script might not work for you if copied 1:1. But i suppose you get the idea.

How HTML5 Web Workers make unicorns run

A unicornOne of the things that HTML5 brings us is Web Workers. These things are great for enhancing user experience in webapplications or javascripts that contain heavy computations or other sort of long running scripts.

Web Workers are like threads, which you might know from other development platforms. The definition of threading is the following according to Wikipedia:

“The threaded programming model provides developers with a useful abstraction of concurrent execution.”

Let’s start with identifying the problem.
For the working example for this post, check out this page and hit the ‘Freeze’ button. Under this freeze button there is a function that does a huge secret calculation that is supposed to use a lot of your CPU’s time. Actually it’s not that secret, see code sample 1 for the code. Notice that the unicorn stops moving for a while when you press that button. The freeze function is freezing the UI while executing. (Thank you Captain Obvious). See diagram 1.

// Code sample 1 - Secret freeze function
function freeze() {
    var total = 0;
    for (var i = 0; i < 100000; i++)
        for (var k = 0; k < 20000; k++) total++;
    return total;
}

Diagram 1 - Single threaded script execution

Obviously, this causes the user to wait, and that’s bad practice. Nobody likes to wait.
Web Workers enable you to start another thread that can process computations parallel to the browser’s so-called UI thread. (That executes your “normal” javascript)
With the result of not blocking the user interface.
Simply put; you delegate your heavy computations to another process, which, when ready, will send the result back to your UI thread. This is visualized in diagram 2.

Diagram 2 - Multi threaded script execution

Delegating the long running function to another thread leaves computing space in the UI thread open for other computations. UI computations of course, as it is the UI thread.
Doing this is actually quite simple, and requires to put your code in a new javascript file that will  execute in the worker’s context. Running a script in the worker context means that the script does not have access to the DOM or anything else that is not thread-safe.

Exchanging data between the UI and Worker is being done by the Worker.postMessage method. This method requires one parameter, the data you want to send.
This data is internally serialized as JSON by most browsers to prevent callbacks or other pointers being passed (which would potentially cause cross thread errors). (source)
Code example 2 demonstrates how to create a worker in javascript, and code example 3 demonstrates how the worker script itself should be defined. Notice that event handlers/callbacks are used to start and communicate between the Worker and the UI thread.

// Code example 2 - Creating the Worker and listen to onmessage
var worker = new Worker('webworker.js');
worker.addEventListener('message', function (event) {
    document.getElementById('calculation').textContent = event.data;
}, false);
// Code example 3 - webworker.js
self.addEventListener('message', function(event) {
    var total = 0;
    for (var i = 0; i < 100000; i++) {
        for (var k = 0; k < 30000; k++) {
            total++;
        }
    }
    self.postMessage(total);
}, false);

Inside webworker.js, the self keyword is used to approach the Worker’s API. In here you also see that we add a listener to the onmessage event, and use the Worker.postMessage method to send the output back to the UI thread.
You can start the worker from the UI thread (your normal HTML page or javascript) by using the Worker.postMessage method, as seen in code example 4.

// Code example 4 - Starting the worker
var worker = new Worker('webworker.js');
worker.addEventListener('message', function (event) {
    document.getElementById('calculation').textContent = event.data;
}, false);

worker.postMessage(null); // postMessage parameter accepts everything that’s serializable.

Obviously, you don’t want to stop a unicorn from running across your screen. So if you delegate the freeze function to a Web Worker, you get the result as in diagram 3.

Diagram 3 - Delegate the big calculation to another thread/worker, so the unicorn can keep running

Now click the “Via worker” button in the working example page.
Yay awesome, the unicorn can continue to run across your screen in the meantime! So yes, that’s what Web Workers are good for, making unicorns run across your screen.

No but seriously, i couldn’t think of a more interesting use-case.. But you can fill in your own use-case for a long running function that causes the UI thread to block.

Of course, you want to know in which browsers Web Workers are supported. Fortunately, on desktop browsers the Web Workers are widely supported (although, IE10+). A bit less fortunate is the support on mobile browsers, with the exception of Opera Mobile 11 no mobile browser supports Web Workers. For a comprehensive overview of supported browsers, take a look at the MDN page “Using web workers”.

A more in-depth explanation of HTML5 Web Workers can be found at the HTML5 Rocks website.

Javascript beyond the browser

As a web developer, i am using javascript on a daily basis.
I use it to manipulate elements in the DOM, set css properties, animate objects, interact with user elements, etc. etc.
Now i can’t say that i’m a true javascript ninja, but let’s say javascript and i get along pretty well. I like writing javascript; it’s a flexible, easy to write language, and there are some excellent frameworks that makes life a whole lot easier. Especially when writing cross-browser compatible code.

All the above mentioned usage of javascript is from within the browser, on the client side.
About a couple of weeks, click-happy as i am with links on Twitter i stumbled upon this talk about Node.JS by Ryan Dahl on Ontwik (great website for technical screencasts!).

Now the first thing that got my attention was that Ryan was visibly nervous, and i wanted to see how he made it through the hour. But soon the contents of this talk became my main point of attention. It’s very interesting how Node.JS’ approach to I/O operations leads to high scalability in terms of concurrent users. Now if you are interested in Node.JS specifically, i would suggest viewing this talk, and i’m not going into details in this post.
(Although Node.JS is on my “things to write about” list)

A week or two after that, i was experimenting with PhoneGap, an “Open Source framework for building cross-platform mobile apps”. PhoneGap enables a developer to create mobile apps (for iOS, Android, Symbian, Windows Mobile, BlackBerry and Palm) using HTML, CSS and javascript.
Now the best thing is you can still use platform specific core features like camera, contacts, geolocation or network.

After playing around a bit i got this great idea about using my laptop’s browser, a Phonegap app and a Node.JS server app to link up my mobile phone with my laptop. This enables real-time interaction between the two (or three, or four, or five)!! Now how awesome is that?!

First off an Android app with PhoneGap would send data from the phone’s accelerometer using ajax (but streams are excellent for this purpose aswell) to a Node.JS server application.
The Node.JS app would then broadcast it to all browser clients,  who will then *do stuff* with the data received from the phone.
Eventually i got this communication between my mobile phone, server app and browser running in real-time, which is what it was all about. Pretty awesome!

Now both of these (at least to me) ‘new’ technologies put javascript in a whole different perspective for me. I already knew the javascript language, but didn’t realize it has a lot more potential than just manipulating the DOM.

The use of javascript outside the browser has been a trending topic for quite some time now, but i’ve always been a bit in doubt of how this would be a good addition to our current stack of of tools, and how it would make a developer’s life easier.
Node.JS and PhoneGap proved to be very easy to use, and opened a new perspective of interaction to me.
Profit++!

If you know how to write javascript, don’t limit yourself to the browser!