GWT 2.0 was released today, and even though I've been using it for months and contributing to it, I didn't realize the significance of this release until I saw the Google Campfire event, because I've been exposed to each new feature incrementally, rather than all at once. If you take a step back, look at what has been accomplished since 1.7:
- Development Mode
- UI Binder
- Following the GWT mantra "Why do at runtime what you can do at compile time?" UIBinder is an extensible declarative language for constructing user interfaces, injecting those constructs into your Java code, and optimizing and bundling resources like stylesheets, images, and localized text. While it may seem like a throwback to use XML/XHTML in an era when HTML5 tagsoup and JSON are emerging as favorites, you have to consider what has been bought in exchange. UiBinder constructs HTML at compile time, which means it minimizes the number of DOM operations needed to get your UI up and running. It treats stylesheets as an intelligence resource, obfuscating and compressing them just as the GWT compiler does for JS, as well as providing local scope for CSS classes so that you can compose stylesheets written by different parties together without worrying about conflicts.
- Google Eclipse Plugin
- Technically, it's separate from GWT, but I'll list it here because of its tight integration with GWT. It provides intelligent integration between your Java source, JSNI methods, and UiBinder files. Again, this product alone would be a major event unto itself, but it's almost under-the-radar in Google's Campfire event.
- Code Splitting
- The value that whole-program compilation for JS brings to the table is no better demonstrated than it is here, by the ability of the GWT compiler to statically compute transitive callgraphs and dependencies from any callsite you desire, and split off that chunk of code for deferred loading. Ask yourself, if I handed you a hand-written large JS application like Maps, or GMail, or Y! Mail, how long would it take you to fully modularize all of the libraries used, get all of the dependencies exactly right (if you need feature F, load library F, but F needs G and H, so load libraries G and H). You can point to popular JS libraries using complex JS module loaders with dependency management, but keep in mind, that is all done by hand, on very mature libraries. GWT Code Splitting brings this functionality to mere mortals in just a few lines of code.
- Constraint-Based Layout
- Many modern JS libraries have punted on making CSS work for general compose-able widgets, and rely on JS to perform layout calculations for widgets. This works well, but has the downside of laggy performance, as the browser rendering engines are optimized for layout calculations, and often performing JS layout can cause excessive browser layouts. You'll see this in split panels or scroll panes sometimes as the divider or scrollbar lagging the mouse position. Joel Webber of the GWT team has finally cracked the code to make CSS based layouts work in a predictable fashion, and as a result, you can now compose arbitrary layouts in GWT with predictability, a productivity enhancement unto itself, even if some flexibility is lost, end-user performance and development speed are gained.
- Few people realize that GWT has been doing automated image sprites for a long time. ImageBundle, introduced in GWT 1.4, allowed GWT users to simply refer to images on disk, and the compiler would pack all of those images into a single file, transforming references to the images automatically into sprites. Then with 1.5/1.6, FooBundle, or ImmutableResourceBundle was introduced to the GWT Incubator. FooBundle/IRB took spriting to the next level by allowing all of your resources to be bundled into one or more files, or even inlined in your compiled JS as a gigantic data URI. GWT 2.0 introduces IRB into the core SDK, now called ClientBundle, it has been enhanced and polished. Simply put, ClientBundle allows GWT developers to reduce the number of HTTP requests for resources to just 1 or 2 which are cached forever, pack images optimally, optimize and minify CSS, and much more. Did you know that ClientBundle works with internationalization? That GWT ClientBundle can automatically flip images for Right-To-Left locales like Arabic, and flip CSS rules as well? Crazy awesome!
- Optimized for Compression
- HtmlUnit for Testability
- You want testing? GWT's got you covered. Java tests? Check. Selenium tests? Check. Web-Mode test in real browser? Yep. But what's really new, is that GWT can run tests in a simulated browser environment thanks to HtmlUnit. This has two immediate benefits: 1) You can run your tests anywhere and not have to worry about prepping a test environment or platform specific details and 2) Tests can startup much quicker because they don't need to use a real browser. Again, it would seem like an almost irrelevent footprint if it weren't for the fact that a lot of effort is going into making this work correctly.
- Speed Tracer, 'nuff said!
- 1. It's awesome. 2. It's actually written in GWT. 3. It enables easy collaboration and sharing of traces. 4. It has a plugin mechanism for analyzing traces and providing automated warnings and suggestions like YSlow!. 5. It's awesome. 6. It's awesome!
But wait, there's more! These are just the main bullet points, there's lots of other changes under the hood that are also important, let's look at a few:
- Story of Your Compile, Compile Reports
- Think of it as Compile-Time SpeedTracer. SOYC gives you lots of detail about what each part of your app is contributing to the output in terms of size, and what the interdependencies are. This provides valuable feedback as to where to look to reduce bloat, or split-off code better. This would be the equivalent of a JS tool that looked at your jQuery application, and told you exactly how many bytes were used by each method in each jQuery plugin you're using, and which modules and functions pulled in the others. Think about it.
- Better stack traces, and stack trace emulation for IE6
- Schedule Finally
I could go on, tons of compiler optimizations, Directly Evalable RPC, Conditional Deferred Binding Properties, HTML Standards Mode Support. One could make the argument, that almost everything in this list can be done, or has been done, elsewhere, or in parts of other tools. But that's why GWT is so beneficial. It unifies where other approaches fragment. Sure, you could combine your own code splitting, with your own handrolled JS loader, with someone else's image sprite tool, with another guy's test framework, and someone else's minifier, and this guy's trace analyzer, and that guy's widget toolset. And if you think you could achieve the same outcome, you'd be absolutely right.
GWT isn't about doing what isn't possible elsewhere. It's about making you productive doing it. It isn't about extolling the beauties of Java, it's about pragmatically recognizing the leverage you get from the existing toolchain, IDEs, test harnesses, and types. It isn't about hiding the DOM, CSS, and the browser from you. It's about allowing you to write your abstractions yourself more productively, just like you'd do in hand-coded JS anyway. Someday, there may even be the ability for GWT to compile other languages to Java, or even process JS with type annotations.
GWT makes productive, large scale web development possible, and enables next-gen applications to be built reliably.