Friday, January 15, 2010

Google Web Tools

A while ago I had a post in my Beautiful Code series, on Computer Generated Code. There, I was referring to things like the C pre-processor, which runs through a source code file and generates additional source code, which is finally sent to the compiler. Or, in more extreme cases, using another tool altogether, like awk, to do the same thing, but with potentially a lot more flexibility (with the power of regular expressions at hand). These days Java programmers are doing something similar with Annotations. The article also mentioned code that generates further, optimized code.

Last Fall, I came across a variation on this, in the form of the Google Web Toolkit (GWT), which is a set of tools created by Google for creating rich HTML-based applications, specifically ones that make use of JavaScript and AJAX and JSON to do complex things in the browser.

One of the disadvantages to using a scripting language like JavaScript for development is that it is not a “strongly typed” language, and neither is it compiled, so some development errors will not be discovered until the testing phase. With a compiled, strongly-typed language (such as C++ or Java), some errors can be caught at compile time and fixed quickly, which reduces the number of bugs to be discovered during the testing phase. Another issue is that things often work slightly differently from browser to browser, so often you find yourself building JavaScript code that does things like, “if Firefox do this, but if Internet Explorer version 6, do that, but if IE7 do the other…”

GWT tries to combine the benefits of using a strongly-typed language—in this case Java—with the aforementioned benefits of improved user interface via AJAX. In a GWT application, code is written in Java, and UI is built using a GWT library, very much in the same way that a Java Swing application would be built. Once the application has been built and tested, it is “compiled” into JavaScript, with versions optimized for various browsers. In other words, a version is produced that will be optimized for IE6, and another version for IE7, and another for Google Chrome, and another for Firefox, etc. When the user accesses your application, the GWT JavaScript runtime figures out what browser you’re using, and downloads the correct code (and only the correct code) for your environment.

In addition, any JavaScript which is created is also optimized, whereby extraneous whitespace is removed, comments are elided, and even variable names are shortened; by compacting the JavaScript in this manner, it’s quicker for the browser to download the code, which improves performance even more. For example, a JavaScript function that might normally be written like this

//adds two numbers together, and returns the result
function addTwoNumbers(firstNumber, secondNumber) {
addedNumbers = firstNumber + secondNumber;
return addedNumbers;
}
Might end up looking like this, instead:
function a(a,b){c=a+b;return c;}
Obviously the first version is easier to read, and therefore easier to maintain. As a developer, I would never write code like the second version. But because JavaScript is a scripting language (meaning that it is not compiled into machine language, it is interpreted by the scripting engine at runtime), it means that every byte from that first version gets sent across the network to the browser, comments and whitespace and all. The second version, however, is much smaller, meaning that it will take less time for the browser to download it over the wire. (In this case, the optimized JavaScript is 32 characters, vs. 177 characters for the more maintainable version—something like 82% smaller. Code with a lot of whitespace and comments, and code with long variable and function names, will end up looking a lot smaller in the optimized version, because there’s more stuff that can be stripped out and reduced.)

With GWT, we get the best of both worlds, because the developer works with easy to read, maintainable Java code, but the GWT “compilation” process spits out the more optimized version in JavaScript, to send across the wire.

A typical GWT development lifecycle will be similar to this:
  1. Developer begins developing in Java, using the Google Web Toolkit (quite probably in Eclipse, using the GWT Eclipse plug-ins)
  2. Developer tests code using the provided runtime; at this point the code is still Java code, allowing the developer to set breakpoints and debug
  3. Once the development is complete, the developer “compiles” the GWT application, to create the JavaScript, HTML, and CSS files
  4. These JavaScript, HTML, and CSS files are included in the larger web application
Of course, as development proceeds, the developer may be repeating steps 2–4.

The GWT compilation process can be controlled using normal Ant built scripts, so the overall build process for Java applications can be modified to include a build of the GWT code, and inclusion into the appropriate location in the larger WAR/EAR. For non-Java projects, you can simply “compile” your GWT code, and include the generated files (HTML and JavaScript and CSS and images) in your application.

It’s similar to what we talked about in the Computer Generated Code post; the code that you maintain, and actually work with as a developer, is strongly-typed, clean Java code, with all the comments and whitespace and readable variable names that you are used to. But the code that is actually produced for use at runtime is highly optimized, unreadable code, intended to be seen only by a machine, not a human.

The limitation will be how good GWT is at turning your Java code into JavaScript code. When I did a Proof of Concept application back in the Fall, for an AJAX application we were intending to build at work, I did two versions, one in “raw” JavaScript, and another using GWT. I found that the performance of the “raw” version was better than the GWT version—but, that being said, because of the nature of the GWT libraries, I ended up having to change how I did some things, so it’s not like the code was the same in both cases. It wasn’t a strict apples-to-apples comparison.

For the real application, we decided to use GWT anyway, though, for two reasons:
  1. Our developers are more familiar with Java than JavaScript, so the benefit of maintaining Java code instead of JavaScript was a big one. Especially since the application is a Java EE application; our Ant scripts could simply be updated to include steps to compile the GWT code, and then copy the resultant output files into the main application’s WAR file.
  2. A lesser reason is that there is a possibility that further optimizations might be introduced to GWT, improving the way it produces its JavaScript code. It’s possible that an updated version of GWT might produce even better JavaScript output. (Although it may also force us to change the way that we write our Java, so we can’t expect it to just magically make our code faster.)
GWT has been used to build numerous products/projects—including Google Wave, I might add—so it’s being used by real people to solve real problems. But there are also people who are skeptical about it, and when I was researching the best AJAX libraries to use for my project, I saw mixed reactions to the GWT way of doing things. However, I think it’s another great example of doing something similar to what we discussed in the Computer Generated Code post. Writing code in a manner that is more developer-friendly, and outputting code that is more machine-friendly (and, in this case, network-friendly).

0 comments: