209

We're starting to make heavier use of GWT in our projects, and the performance of the GWT compiler is becoming increasingly annoying.

We're going to start altering our working practices to mitigate the problem, including a greater emphasis on the hosted-mode browser, which defers the need to run the GWT compiler until a later time, but that brings its own risks, particularly that of not catching issues with real browsers until much later than we'd like.

Ideally, we'd like to make the GWT compiler itself quicker - a minute to compile a fairly small application is taking the piss. However, we are using the compile if a fairly naive fashion, so I'm hoping we can make some quick and easy gains.

We're currently invoking com.google.gwt.dev.Compiler as a java application from ant Ant target, with 256m max heap and lots of stack space. The compiler is launched by Ant using fork=true and the latest Java 6 JRE, to try and take advantage of Java6's improved performance. We pass our main controller class to the compiler along with the application classpath, and off it goes.

What else can we do to get some extra speed? Can we give it more information so it spends less time doing discovery of what to do?

I know we can tell it to only compile for one browser, but we need to do multi-browser testing, so that's not really practical.

All suggestions welcome at this point.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • Yo, this is the top-rated GWT question ever asked, and it's been around for a solid 13 years now. Crazy to see how far GWT has come since then! Nowadays, if you wanna chat with GWT devs, hit up the Gitter community at https://app.gitter.im/#/room/#gwtproject_gwt:gitter.im. – quarks Feb 20 '23 at 06:33

10 Answers10

147

Let's start with the uncomfortable truth: GWT compiler performance is really lousy. You can use some hacks here and there, but you're not going to get significantly better performance.

A nice performance hack you can do is to compile for only specific browsers, by inserting the following line in your gwt.xml:

<define-property name="user.agent" values="ie6,gecko,gecko1_8"></define-property>

or in gwt 2.x syntax, and for one browser only:

<set-property name="user.agent" value="gecko1_8"/>

This, for example, will compile your application for IE and FF only. If you know you are using only a specific browser for testing, you can use this little hack.

Another option: if you are using several locales, and again using only one for testing, you can comment them all out so that GWT will use the default locale, this shaves off some additional overhead from compile time.

Bottom line: you're not going to get order-of-magnitude increase in compiler performance, but taking several relaxations, you can shave off a few minutes here and there.

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
  • 3
    It appears for GWT 2.0, you actually want this syntax to specify a user agent: – mooreds Feb 10 '10 at 01:19
  • In gwt 2.2 there is no gecko. Compiler states that "The value gecko was not previously defined. Unexpected exception while processing element 'set-property'" – uthark Mar 24 '11 at 02:47
  • setting the value to "gecko1_8" only should work for Firefox 1.5 and later in gwt 2.2 – eaykin Jun 07 '11 at 10:02
  • This answer is almost two years old. Feel free to edit it to clarify this point. – Yuval Adam Jun 08 '11 at 04:39
  • 6
    2013 , still GWT compile time sucks can any one improve this answer for , GWT 2.5 – Asraful Apr 27 '13 at 10:43
  • I'd add also: . W/o this, when ran from Firefox we get: Uncaught Error: Class$S15: Possible problem with your *.gwt.xml module file. The compile time user.agent value (safari) does not match the runtime user.agent value (gecko1_8). Expect more errors. – Cristian Jun 28 '23 at 18:33
64

If you run the GWT compiler with the -localWorkers flag, the compiler will compile multiple permutations in parallel. This lets you use all the cores of a multi-core machine, for example -localWorkers 2 will tell the compiler to do compile two permutations in parallel. You won't get order of magnitudes differences (not everything in the compiler is parallelizable) but it is still a noticable speedup if you are compiling multiple permutations.

If you're willing to use the trunk version of GWT, you'll be able to use hosted mode for any browser (out of process hosted mode), which alleviates most of the current issues with hosted mode. That seems to be where the GWT is going - always develop with hosted mode, since compiles aren't likely to get magnitudes faster.

Chi
  • 22,624
  • 6
  • 36
  • 37
  • 2
    Ah, the localWorkers option is a gem, that's worth knowing. Sadly, most of our dev boxes are single-core xeons. That OOPHM looks very promising, too. Always in the next version, it is... – skaffman Jun 18 '09 at 13:51
  • 4
    virtualize a compiling enviroment on a box with multiple cores; remote into this vm; execute command line GWT compile using -localWorkers, with minimal locals and user.agents; make sure the box hosting the vm is a network peer to where you are deploying to. The combination of this gets your compile down to about 30 seconds w/ deployment in tomcat. In addition all of this can be written in a script. You can also dev on a local machine, create a svn patch, and have your script apply the patch using some type of NFS or samba sharing, eliminating the need to copy over just the src diffs. yay! – kr. Feb 11 '10 at 20:26
  • NX client is also a huge +++ for remote dev on limited ADSL, Cable, or WiFi connections. Plus you always are in sync no matter what comp you are using at any location w/ internet – kr. Feb 11 '10 at 20:29
  • defaults to platform available number of CPUs in maven build. So no speed up here for me. – keiki Apr 09 '15 at 08:52
56

Although this entry is quite old and most of you probably already know, I think it's worth mention that GWT 2.x includes a new compile flag which speeds up compiles by skipping optimizations. You definitely shouldn't deploy JavaScript compiled that way, but it can be a time saver during non-production continuous builds.

Just include the flag: -draftCompile to your GWT compiler line.

monzonj
  • 3,659
  • 2
  • 32
  • 27
  • 4
    I used that option, and in our project sometimes it failed with a strange error. So be aware, that sometimes the compilation might not work because of this. – Vic Aug 12 '12 at 10:38
32

Here is a list of user.agent values you can set it to.

(Adding this here because I keep ending up here when I search for what I should set to make it only produce a permutation for chrome. Answer is: <set-property name="user.agent" value="safari"/>)

James McManus
  • 66
  • 1
  • 5
Stephen
  • 329
  • 3
  • 2
  • Where am I supposed to add this set-property element? I've tried adding it inside and outside of the element in my app.gwt.xml file and it doesn't work. – Alex Worden May 14 '12 at 06:04
  • It goes in your module ABC.gwt.xml file where ABC is your module name. – Glenn Jul 26 '12 at 22:26
30

In the newer versions of GWT (starting either 2.3 or 2.4, i believe), you can also add

<collapse-all-properties />

to your gwt.xml for development purposes. That will tell the GWT compiler to create a single permutation which covers all locales and browsers. Therefore, you can still test in all browsers and languages, but are still only compiling a single permutation

Chi
  • 22,624
  • 6
  • 36
  • 37
  • 2
    Interesting... what's the downside? – skaffman Nov 21 '11 at 19:08
  • compiling a single permutation that handles all browsers and languages still takes a little bit more time than a single permutation that handles only one browser and language, but the difference isn't significant in my experience. (~25% more is what i'm seeing, but that is still a huge improvement over compiling multiple permutations) – Chi Nov 21 '11 at 22:28
  • I can't find a doc link for this... can you link to something? – skaffman Nov 21 '11 at 22:39
  • Although this tag speeds up compilation, it also breaks debugging in Super Dev Mode (at least for 2.6). Source code shown in chrome debugger differs from compiled js code. So when I put a breakpoint in some java method, debugger stops in another method. – Konstantin Milyutin Dec 09 '14 at 09:30
19

You can add one option to your build for production:

-localWorkers 8 – Where 8 is the number of concurrent threads that calculate permutations. All you have to do is to adjust this number to the number that is more convenient to you. See GWT compilation performance (thanks to Dennis Ich comment).

If you are compiling to the testing environment, you can also use:

-draftCompile which enables faster, but less-optimized compilations

-optimize 0 which does not optimize your code (9 is the max optimization value)

Another thing that more than doubled the build and hosted mode performance was the use of an SSD disk (now hostedmode works like a charm). It's not an cheap solution, but depending on how much you use GWT and the cost of your time, it may worth it!

Hope this helps you!

Gray
  • 115,027
  • 24
  • 293
  • 354
martins.tuga
  • 1,662
  • 1
  • 16
  • 20
  • Setting local workers to the number of cores can be very unproductive. See this for reference: http://josephmarques.wordpress.com/2010/07/30/gwt-compilation-performance/ – Dennis Ich Mar 05 '14 at 14:40
  • Thanks for you comment Dennis. Actually, I have an SSD and give 2G of memory. Of course that the number of localWorker must be tuned to each case, depending on the number of permutations, cores, machine, etc... In my case, when I'm compiling on my laptop and want to navigate on the web, if leave 2 cores free. That's just an example. However, will edit my post to include your idea. Thanks. – martins.tuga Mar 14 '14 at 18:55
14

The GWT compiler is doing a lot of code analysis so it is going to be difficult to speed it up. This session from Google IO 2008 will give you a good idea of what GWT is doing and why it does take so long.

My recommendation is for development use Hosted Mode as much as possible and then only compile when you want to do your testing. This does sound like the solution you've come to already, but basically that's why Hosted Mode is there (well, that and debugging).

You can speed up the GWT compile but only compiling for some browsers, rather than 5 kinds which GWT does by default. If you want to use Hosted Mode make sure you compile for at least two browsers; if you compile for a single browser then the browser detection code is optimised away and then Hosted Mode doesn't work any more.

An easy way to configure compiling for fewer browsers is to create a second module which inherits from your main module:

<module rename-to="myproject">
  <inherits name="com.mycompany.MyProject"/>
  <!-- Compile for IE and Chrome -->
  <!-- If you compile for only one browser, the browser detection javascript
       is optimised away and then Hosted Mode doesn't work -->
  <set-property name="user.agent" value="ie6,safari"/>
</module>

If the rename-to attribute is set the same then the output files will be same as if you did a full compile

Gray
  • 115,027
  • 24
  • 293
  • 354
David Webb
  • 190,537
  • 57
  • 313
  • 299
11
  • Split your application into multiple modules or entry points and re-compile then only when needed.
  • Analyse your application using the trunk version - which provides the Story of your compile. This may or may not be relevant to the 1.6 compiler but it can indicate what's going on.
Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
  • Multiple entry points should work, but not modules because GWT always checks everything connected to your code and compiles a monolithic end result. The GWT framework is a mess and a disgrace to modularity principles. Didn't find one good project that re-used GWT framework stuff. – user1050755 May 15 '17 at 17:36
4

For GWT 2.x I just discovered that if you use

<set-property name="user.agent" value="ie6"/>
<extend-property values="ie8,gecko1_8" name="user.agent"/>

You can even specify more than one permutation.

CCarpo
  • 41
  • 2
0

You can compile specific module of gwt Just you need to mention which module to be compiled in build.xml of your project.

With the help of the command below

ant -Dap.build.javadoc gwt
Mario Varchmin
  • 3,704
  • 4
  • 18
  • 33
faizan9689
  • 21
  • 1