With Google Web Toolkit (GWT), you write your
AJAX
front-end in the Java programming language whichGWT
then cross-compiles into optimized JavaScript that automatically works across all major browsers.
…claims Google. And I must say, I’m pretty impressed by the ease of development GWT
offers. I’ve used it at work on a project that I probably couldn’t have done without it, given my poor JavaScript skills. Especially the fact that you don’t have to worry about whether your code works in all browsers is great.
There are a couple of caveats, however:
- The set of supported Java classes is limited, which sometimes causes confusion. For instance, there is a
Character
class, but theisWhitespace()
method is not supported. And neither isList.subList()
. - Serialization works differently from the Java standard.
- You can’t work with regular
W3C DOM
objects on the client. Instead,GWT
provides it’s ownDOM
hierarchy. - Even though Google claims that
GWT
“allows developers to quickly build and maintain complex yet highly performant JavaScript front-end applications in the Java programming language”, performance can be a problem.
The purpose of this post is to elaborate on that last point.
Java isn’t JavaScript
Most developers evolve a sense of intuition about what type of code can be a performance problem, and what not. The problem with GWT
development, however, is that even though you write Java code, the browser executes JavaScript code. So any intuitions about Java performance are misleading.
Therefore, your usual rules of thumb won’t work in GWT
development. Here’s a couple that may.
Serialization is slow
Our application created a domain model on the server, serialized that to the client, and had the client render it. The problem was that the model could become quite large, consisting of thousands of objects. This is not something that GWT
currently handles well. Serialization performance appears to be proportional to the number of objects, not just to their total size. Therefore, we translated the model to XML
, and serialized that as a single string. This was way faster.
However, this meant that we needed to parse the XML
on the client side to reconstruct our model. GWT
provides an XMLParser
class to handle just that. This class is very efficient in parsing XML
, but it turned out that traversing the resulting DOM document
was still too slow.
So I wrote a dedicated XML
parser, one that can only parse the subset of XML
documents that represent our domain model. This parser builds the domain model directly, without intermediate representation. This proved to be faster than the generic approach, but only after being very careful with handling strings.
Some string handling is slow, particularly in Internet Explorer
Java developers know that string handling can be a performance bottleneck. This is also true for GWT
development, but not in quite the same way. For instance, using StringBuffer
or StringBuilder
is usually sufficient for improving String
handling performance in Java code. But not so in JavaScript. StringBuffer.append()
can be very slow on Internet Explorer, for instance.
GWT
1.6 will contain its own version of StringBuffer
that will alleviate some of these problems. Since 1.6 isn’t released yet, we just copied this class into our project.
But even with the new StringBuffer
class, you still need to be careful when dealing with strings. Some of the StringBuffer
methods are implemented by calling toString()
and doing something on the result. That can be a real performance killer. So anything you can do to stay away from substring()
, charAt()
, etc. will help you. This can mean that it’s sometimes better to work with plain String
s instead of StringBuffer
s!
Tables
For displaying data in a table-like format, you can use the Grid
widget. This is not terribly fast, however, so you may want to consider the bulk table renderers.
The downside of these is that they translate any widgets you insert into the table to HTML
, and you loose all the functionality to attached to them, like click handling. Instead, you can add a TableListener
, that has a onCellClicked()
method.
Varargs are slow
Variable argument lists are sometimes quite handy. However, we’ve found that they come at a severe performance penalty, because a JavaScript array needs to be created to wrap the arguments. So if at all possible, use fixed argument lists, even though this may be less convenient from a code writing/maintaining perspective.
Don’t trust rules of thumb, use a profiler
The problem with rules of thumb is that they are just that: principles with broad application that are not intended to be strictly accurate or reliable for every situation. You shouldn’t put all your trust in them, but measure where the pain really is. This means using a profiler.
You could, of course, run your favorite Java profiler against hosted mode to get a sense of performance of your code. But that would be besides the point. Your Java code is compiled to JavaScript and it is the JavaScript code that gets executed by the browser. So you should use a JavaScript profiler.
We used Firebug to profile the compiled JavaScript code and this helped us enormously. As usual with profiling, we found performance bottlenecks that we didn’t anticipate. As a result, we were able to make our application load over 60 times faster! (on Internet Explorer 7)
Performance in different browsers
The only problem with Firebug is that it’s a FireFox plugin, and therefore not available for Internet Explorer. [Firebug Lite doesn’t contain a profiler.] Not that I personally would want to use IE, but our customers do, unfortunately.
The irony is that you need a JavaScript profiler in Internet Explorer the most: FireFox is unbelievably much faster than Internet Explorer when it comes to processing JavaScript, especially with string handling. For instance, for one data set, FireFox 3 loaded the page in 51 seconds, while Internet Explorer 7 took 12 minutes and 4 seconds!
Internet Explorer 8 will supposedly be better:
We have made huge improvements to widely-used JScript functionality including faster string, array, and lookup operations.
We’ll have to see how that works out when IE8 is released…
BTW, if you’re interested in browser performance, check out this comparison.
Hi, I am working with GWT on Eclipse, & what astounds me is that it is EXTREMELY SLOW. I was wondering, did you & your team figured out a way to fix this? Eclipse so slow on GWT that it is bearly usable & it is wasting alot of my development time.
I haven’t worked with GWT in a loooong time, so I’m afraid I can’t be of much help here. Sorry. I hope you figure it out and then share your solution.
Good compilation, secure coding is need for todays Java programming. I also suggest looking http://javarevisited.blogspot.com.ar for some Java best practices. I regularly follow and like it
Usually I do not read article on blogs, however I would like to say that this write-up very forced me to try and do so! Your writing taste has been amazed me. Thanks, very great post.
Thanks for the helpful post! Great advice on varargs, Strings, etc.
DynaTrace has a nice free JS profiler that works in IE6/7.
Interesting story, I did not thought this was going to be so interesting when I saw the title with link.
Hi,
great article! Wondering how you could improve performance in IE7 if you hadn’t the chance to use a profiler on it?
Thanks
Dominik
Dominik,
I improved performance on IE7 by profiling on FireFox for getting an idea and then testing in IE7 to see if the idea was actually an improvement. I’m sure this is not a perfect method, but it did work in my case.
Very nice article.
For that ones who does not like the GWT´s serialization I would like to suggest the XStream (http://xstream.codehaus.org/), pretty easy to use. I´m working with it along GWT and the result has been very cool.
Gyo
Hi, I want to use XStream with GWT. I have written code in GWT application using XStream but when I run application, it threw an error with messages
“[ERROR] Line 235: No source code is available for type com.thoughtworks.xstream.XStream; did you forget to inherit a required module?”
and
“[ERROR] Line 235: No source code is available for type com.thoughtworks.xstream.io.xml.DomDriver; did you forget to inherit a required module?”
How to integrate XStream jar file with GWT application. I got this error while run application in Hosted mode.
Please help asap.
Thanx.
You can use XStream on the *server* side, but not on the *client* side. GWT will only compile your Java source to JavaScript, not any jars you might want to use. You could add the XStream Java *source* to your project, but chances are it uses something else that is not supported by GWT.
Hi,
how to user XStream in GWT? If I use it at Server side convert POJO to xml, then how to convert from XML to POJO at client side.
From what I’ve been reading, I don’t think this can be done automatically. From the client side, you can implement the reading from a JSON string as follows:
public static native JavaScriptObject parseJson(String jsonStr) /*-{
return eval(jsonStr);
}-*/;
However what you get is an xml representation of your POJO not the JSON format, so this is a dead end. Another way is in your client-side to have your classes take an xml string and fill their fields. No good! If you can up with a good solution let me know
Are the performance problems related to java.io.Serializable or IsSerializable or both?
http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-5&t=FAQ_RPCSerializationSupport
@kail: From the page you are referring to:
“The solution is Firebug Lite, a JavaScript file you can insert into your pages to simulate some Firebug features in browsers that are not named “Firefox”.”
Note the phrase “some Firebug features”. Unfortunately, profiling isn’t one of them, as you can see in the screen shot on that same page: There are Inspect and Clear buttons, but there is no Profile button.
Well, you can use Firebug with IE, Opera or Safari http://getfirebug.com/lite.html
Check this out.
Nice post, and especially great advice: for anything crucial, measure!