efficiency of my gwt application

44 views
Skip to first unread message

ytbryan

unread,
Apr 15, 2009, 7:51:04 AM4/15/09
to Google Web Toolkit
hi folks,

my application has been running very slowly and i would like to know
why.
can somebody advise me on what are the common bottleneck that i need
to optimise? I am pretty new with gwt.

i read the " speed up gwt compiler series
http://blog.bazoud.com/post/2008/07/31/Can-I-speed-up-the-GWT-compiler-Part-III
but i think it is quite irrelevant in speeding up the running speed of
the application. correct me if i am wrong.

i copy my gwt.xml if it is necessary. i have rpc, google map, ofcgwt,
smartgwt inside the application.

<?xml version="1.0" encoding="UTF-8" standalone="no"?><module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name="com.google.gwt.user.User"/>
<inherits name="com.smartgwt.SmartGwt"/>
<inherits name="com.smartgwt.SmartGwtNoScript"/>
<inherits name="com.smartclient.theme.enterprise.Enterprise"/>
<inherits name='com.rednels.ofcgwt.OFCGWT'/>
<inherits name="com.google.gwt.maps.GoogleMaps" />
<!-- Specify the app entry point class. -->
<entry-point class="com.eviware.gwt.test.mysqlconn.client.MySQLConn"/
>
<script src="http://maps.google.com/maps?gwt=1&amp;file=api&amp;v=2" /
>
<!-- servlet context - path is arbritray, but must match up with
the rpc init inside java class -->
<!-- Tomcat will listen for this from the server and waits for rpc
request in this context -->
<servlet
class="com.eviware.gwt.test.mysqlconn.server.MySQLConnServiceImpl"
path="/MySQLConnService"/>
</module>


thank you!

Thomas Broyer

unread,
Apr 15, 2009, 9:13:25 AM4/15/09
to Google Web Toolkit


On 15 avr, 13:51, ytbryan <ytbr...@gmail.com> wrote:
> hi folks,
>
> my application has been running very slowly and i would like to know
> why.

You could try compiling in -style DETAILED (or at least PRETTY) and
run a JavaScript profiler (Firebug or IE8 developer tools).
GWT comes with a benchmark framework, but you'd have to know what you
want/have to measure...

> can somebody advise me on what are the common bottleneck that i need
> to optimise? I am pretty new with gwt.

1. optimize network exchanges (generally, you'd better have 1 RPC call
return 3 "kinds" of data, than 3 RPC calls)
2. but GWT-RPC might be slow, particularly while serializing/
deserializing large object graphs
3. when updating the UI, working with hidden (display:none) or, even
better, detached widgets is faster; sometimes, building a new widget
"from scratch", populating it and replacing an existing equivalent
widget might be faster than updating the existing widget
4. rendering-wise, try to set table-layout:fixed on your tables
(including Horizontal/VerticalPanel, FlexTable, Grid, DecoratorPanel,
DecoratedPopupPanel, DialogBox, etc.)

5. what does "slow" mean?

ytbryan

unread,
Apr 15, 2009, 9:52:10 AM4/15/09
to Google Web Toolkit
thanks for your reply thomas. for me, there is two cases of slowness.

- the rpc is quite slow. i am using it to return a few thousand by
eleven column of data(String)....
- i have a tabset within my application which i copied from the
smartgwt showcase.... when i click on new tab with google map on
it...... it will normally hang and need a few minutes to finally
display the result. sometimes, it will hang forever.

can you give me some links to these tutorials? if you have any.....

thanks again..

ytbryan

unread,
Apr 15, 2009, 10:06:33 AM4/15/09
to Google Web Toolkit
thanks for your reply thomas. for me, there is two cases of slowness.

- the rpc is quite slow. i am using it to return a few thousand by
eleven column of data(String)....
- i have a tabset within my application which i copied from the
smartgwt showcase.... when i click on new tab with google map on
it...... it will normally hang and need a few minutes to finally
display the result. sometimes, it will hang forever.

can you give me some links to these tutorials? if you have any.....

thanks again..

On Apr 15, 3:13 pm, Thomas Broyer <t.bro...@gmail.com> wrote:

ytbryan

unread,
Apr 15, 2009, 10:51:36 AM4/15/09
to Google Web Toolkit
thanks for your reply thomas. for me, there is two cases of slowness.

- the rpc is quite slow. i am using it to return a few thousand by
eleven column of data(String)....
- i have a tabset within my application which i copied from the
smartgwt showcase.... when i click on new tab with google map on
it...... it will normally hang and need a few minutes to finally
display the result. sometimes, it will hang forever.

can you give me some links to these tutorials? if you have any.....

thanks again..

On Apr 15, 3:13 pm, Thomas Broyer <t.bro...@gmail.com> wrote:

Vitali Lovich

unread,
Apr 15, 2009, 12:32:41 PM4/15/09
to Google-We...@googlegroups.com
Your problem is probably using SmartGWT which is known to be quite slow.

gregor

unread,
Apr 15, 2009, 1:52:21 PM4/15/09
to Google Web Toolkit
>
> - the rpc is quite slow. i am using it to return a few thousand by
> eleven column of data(String)....

a) RPC is *much* slower in hosted mode than deployed in web mode. You
should time your RPC performance (separately to the table "draw" time)
when deployed to find out how it is really performing
b) having said that, fetching several thousand rows of data and
displaying it in one operation is likely to be unacceptably slow. It
takes javascript engines quite a long time attach thousands of HTML
elements to the DOM. It is generally much faster to do it in page-
fulls even though it takes multiple RPC calls to do it that way. You
might want to check out the PagingScrollTable in the incubator.

> - i have a tabset within my application which i copied from the
> smartgwt showcase.... when i click on new tab with google map on
> it...... it will normally hang and need  a few minutes to finally
> display the result. sometimes, it will hang forever.
>

SmartGWT is a GWT wrapper around a javascript library. It might be
difficult to figure out why it is not performing well for your use
case, and very difficult to do anything about it if you can. Generally
speaking, if you use pure GWT you will get higher performance and more
flexibility and code transparency.

Jason Essington

unread,
Apr 15, 2009, 5:11:28 PM4/15/09
to Google-We...@googlegroups.com

On Apr 15, 2009, at 8:51 AM, ytbryan wrote:

> thanks for your reply thomas. for me, there is two cases of slowness.
>
> - the rpc is quite slow. i am using it to return a few thousand by
> eleven column of data(String)....

There are probably two issues here, one the speed of the RPC, and the
second the speed of populating the table.

But at issue is the attempt to return 33,000 cells worth of data in
one shot. how much of this data is going to be immediately visible to
the user? How likely is the user to use all of this data immediately?
Does your use case present you the opportunity to fetch this data in
some paged way?

you need to figure out how much of your time is spent with the RPC
(deserialization) and how much is spent rendering the table. I would
be inclined to believe that you are likely to find that most of the
time is actually spent rendering the 33,000 cells. however you do have
some options here.
You can move the rendering into an IncrementalCommand which will draw
a few rows at a time which gives the appearance of a much more
responsive application, and will begin rendering immediately, rather
than waiting until all rows are populated before showing the data on
screen.

If your RPC data graph is pretty large, you could switch away from RPC
and use a JSON data graph with Javascript Overlay types on the client
side. a javascript eval() of the object graph from JSON is quite a bit
(like orders of magnitude) faster than RPC deserialization with very
large object graphs. NOTE your design shouldn't rely on large object
graphs, paging is a much better option.

And as gregor mentioned, if you are profiling your code in hosted
mode, the performance has no correlation with real life. you need to
check the performance in web mode, and remember that something that
happens instantaneously in Firefox or Safari (or chrome) could take
forever in IE (particularly IE6), its javascript engine operates at a
glacial speed when compared to other options.

> thanks again..

good luck

-jason

ytbryan

unread,
Apr 15, 2009, 6:44:17 PM4/15/09
to Google Web Toolkit
thank you all for your advices... i learn something new again
today..... :D

On Apr 15, 11:11 pm, Jason Essington <jason.essing...@gmail.com>
wrote:

Arthur Kalmenson

unread,
Apr 15, 2009, 10:56:06 PM4/15/09
to Google-We...@googlegroups.com
An easy thing you might want to try is to render the table detached
from the DOM. This would ensure that you're not doing any DOM
operations when building the table, which is generally very slow. That
should be easy to implement if you grab the table's parent.

--
Arthur Kalmenson

alex.d

unread,
Apr 16, 2009, 2:23:20 AM4/16/09
to Google Web Toolkit
How do you detach the table from the dom, assuming you can have it's
parent with table.getParent() ?

On 16 Apr., 04:56, Arthur Kalmenson <arthur.k...@gmail.com> wrote:
> An easy thing you might want to try is to render the table detached
> from the DOM. This would ensure that you're not doing any DOM
> operations when building the table, which is generally very slow. That
> should be easy to implement if you grab the table's parent.
>
> --
> Arthur Kalmenson
>

Vitali Lovich

unread,
Apr 16, 2009, 2:30:24 AM4/16/09
to Google-We...@googlegroups.com
I'm pretty sure that's wrong - inserting things into a table, detached or not, will still result, AFAIK, in DOM operations.

Anyways, if you never add the table to the screen, then it's never attached to begin with.  Or do table.removeFromParent().

Salvador Diaz

unread,
Apr 16, 2009, 4:43:37 AM4/16/09
to Google Web Toolkit
> 3. when updating the UI, working with hidden (display:none) or, even
> better, detached widgets is faster; sometimes, building a new widget
> "from scratch", populating it and replacing an existing equivalent
> widget might be faster than updating the existing widget
> 4. rendering-wise, try to set table-layout:fixed on your tables
> (including Horizontal/VerticalPanel, FlexTable, Grid, DecoratorPanel,
> DecoratedPopupPanel, DialogBox, etc.)

Do you have any benchmarks showing those advantages ? I wasn't aware
of those 2 facts and I find them quite interesting.

Thanks in advance,

Salvador

Thomas Broyer

unread,
Apr 16, 2009, 4:58:59 AM4/16/09
to Google Web Toolkit


On 16 avr, 08:30, Vitali Lovich <vlov...@gmail.com> wrote:
> I'm pretty sure that's wrong - inserting things into a table, detached or
> not, will still result, AFAIK, in DOM operations.

...but DOM operations on a detached tree is much faster because it
cannot cause a reflow or repaint (same for display:none DOM subtree).
See http://ajaxian.com/archives/browser-reflows-how-do-they-affect-performance
and in general the articles in http://ajaxian.com/by/topic/performance
(you'd have to understand GWT internals to make use of some of the
advices; for instance, queueing [1] maps to GWT's DeferredCommand --do
not forget to push "pause" in the command queue-- and
IncrementalCommand; and the memoizer can hardly be done as proposed
without digging into JSNI, though the same result could be achieved in
pure Java using a different, probably non-reusable, pattern)

[1] http://ajaxian.com/archives/speed-up-your-javascript-with-memoization

Vitali Lovich

unread,
Apr 16, 2009, 5:50:49 AM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 4:58 AM, Thomas Broyer <t.br...@gmail.com> wrote:



On 16 avr, 08:30, Vitali Lovich <vlov...@gmail.com> wrote:
> I'm pretty sure that's wrong - inserting things into a table, detached or
> not, will still result, AFAIK, in DOM operations.

...but DOM operations on a detached tree is much faster because it
cannot cause a reflow or repaint (same for display:none DOM subtree).
See http://ajaxian.com/archives/browser-reflows-how-do-they-affect-performance
I think you need to re-read that.  That applies to CSS not Javascript.  Since Javascript is single-threaded (even with HTML5, DOM manipulation can only happen on 1 thread so this is still correct), these will not (at least they shouldn't from what I understand of browsers) trigger any reflows or repaints until the browser gets control back (when you finishing making all your DOM updates or if you use incremental commands).

Thus you shouldn't see any performance benefits over inserting into a detached node or an attached node.

and in general the articles in http://ajaxian.com/by/topic/performance 

(you'd have to understand GWT internals to make use of some of the
advices; for instance, queueing [1] maps to GWT's DeferredCommand --do
not forget to push "pause" in the command queue-- and
I believe that pauses aren't strictly necessary unless you know you absolutely need them because the information in the DOM won't be available until the next iteration of the event loop (I'm not 100% sure on this, so I could be very wrong).

IncrementalCommand; and the memoizer can hardly be done as proposed
Memoization is simply a technique for caching results of expensive calculations - language independant concept (even if expressed differently)

Thomas Broyer

unread,
Apr 16, 2009, 7:07:18 AM4/16/09
to Google Web Toolkit


On 16 avr, 11:50, Vitali Lovich <vlov...@gmail.com> wrote:
> On Thu, Apr 16, 2009 at 4:58 AM, Thomas Broyer <t.bro...@gmail.com> wrote:
>
> > On 16 avr, 08:30, Vitali Lovich <vlov...@gmail.com> wrote:
> > > I'm pretty sure that's wrong - inserting things into a table, detached or
> > > not, will still result, AFAIK, in DOM operations.
>
> > ...but DOM operations on a detached tree is much faster because it
> > cannot cause a reflow or repaint (same for display:none DOM subtree).
> > See
> >http://ajaxian.com/archives/browser-reflows-how-do-they-affect-perfor...
>
> I think you need to re-read that.  That applies to CSS not Javascript.
> Since Javascript is single-threaded (even with HTML5, DOM manipulation can
> only happen on 1 thread so this is still correct), these will not (at least
> they shouldn't from what I understand of browsers) trigger any reflows or
> repaints until the browser gets control back (when you finishing making all
> your DOM updates or if you use incremental commands).
>
> Thus you shouldn't see any performance benefits over inserting into a
> detached node or an attached node.

http://ejohn.org/blog/dom-documentfragments/
and http://www.slideshare.net/julien.lecomte/high-performance-ajax-applications
(slide 33, for example)
(and many other web resources) proves you're wrong.

> > and in general the articles inhttp://ajaxian.com/by/topic/performance
> > (you'd have to understand GWT internals to make use of some of the
> > advices; for instance, queueing [1] maps to GWT's DeferredCommand --do
> > not forget to push "pause" in the command queue-- and
>
> I believe that pauses aren't strictly necessary unless you know you
> absolutely need them because the information in the DOM won't be available
> until the next iteration of the event loop (I'm not 100% sure on this, so I
> could be very wrong).

All deferred commands are run in the same "timer tick" until a pause
is seen. So queuing 3 DeferredCommands in a row without pause won't
have the desired effect.

> > IncrementalCommand; and the memoizer can hardly be done as proposed
>
> Memoization is simply a technique for caching results of expensive
> calculations - language independant concept (even if expressed differently)

yes, hence my "as proposed" (I meant, using the code from the article,
or similar code)

Arthur Kalmenson

unread,
Apr 16, 2009, 9:06:06 AM4/16/09
to Google-We...@googlegroups.com
> Do you have any benchmarks showing those advantages ? I wasn't aware
> of those 2 facts and I find them quite interesting.

I don't, but I do remember some time ago this was discussed (in one of
the presentations or maybe on IRC) and it turned out to be a
substantial speed increase. I'll see what I can dig up.

--
Arthur Kalmenson

Vitali Lovich

unread,
Apr 16, 2009, 9:47:55 AM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 7:07 AM, Thomas Broyer <t.br...@gmail.com> wrote:



On 16 avr, 11:50, Vitali Lovich <vlov...@gmail.com> wrote:
> On Thu, Apr 16, 2009 at 4:58 AM, Thomas Broyer <t.bro...@gmail.com> wrote:
>
> > On 16 avr, 08:30, Vitali Lovich <vlov...@gmail.com> wrote:
> > > I'm pretty sure that's wrong - inserting things into a table, detached or
> > > not, will still result, AFAIK, in DOM operations.
>
> > ...but DOM operations on a detached tree is much faster because it
> > cannot cause a reflow or repaint (same for display:none DOM subtree).
> > See
> >http://ajaxian.com/archives/browser-reflows-how-do-they-affect-perfor...
>
> I think you need to re-read that.  That applies to CSS not Javascript.
> Since Javascript is single-threaded (even with HTML5, DOM manipulation can
> only happen on 1 thread so this is still correct), these will not (at least
> they shouldn't from what I understand of browsers) trigger any reflows or
> repaints until the browser gets control back (when you finishing making all
> your DOM updates or if you use incremental commands).
>
> Thus you shouldn't see any performance benefits over inserting into a
> detached node or an attached node.

http://ejohn.org/blog/dom-documentfragments/
and http://www.slideshare.net/julien.lecomte/high-performance-ajax-applications
(slide 33, for example)
(and many other web resources) proves you're wrong.
I don't believe that it does.  All it says is that DOM manipulation will cause a reflow, which I haven't disagreed with.  I'm disagreeing with your assertion that every single DOM manipulation in a single Javascript execution block will cause a reflow.  You seem to be saying that:

tree t = new tree()
t.addItem("abc");
t.addItem("def");
RootPanel.get().add(t);

will have fewer reflows than

tree t = new tree()
RootPanel.get().add(t)
t.addItem("abc")
t.addItem("def")

According to you (at least from what you've said so far) is that the 1st snippet will cause 1 DOM reflow whereas the below snippet will cause 2, which isn't actually the case AFAIK.  Both will only cause 1 & will be equally fast.

Now if you are doing this in an incremental command, then I don't disagree, although the number of reflows will be the number of times each invocation of the incremental command modifies the DOM.  Although with incremental commands, progressive display may be more important than the slower overall rendering time depending on the size of the data & what the context is).

Ian Bambury

unread,
Apr 16, 2009, 10:46:59 AM4/16/09
to Google-We...@googlegroups.com
2009/4/16 Vitali Lovich <vlo...@gmail.com>


You seem to be saying that:

tree t = new tree()
t.addItem("abc");
t.addItem("def");
RootPanel.get().add(t);

will have fewer reflows than

tree t = new tree()
RootPanel.get().add(t)
t.addItem("abc")
t.addItem("def")

According to you (at least from what you've said so far) is that the 1st snippet will cause 1 DOM reflow whereas the below snippet will cause 2, which isn't actually the case AFAIK.  Both will only cause 1 & will be equally fast.

I think you are both right, depending on the browser you are in.

FF2 (IIRC) will rerender during a sequence where most other browsers won't. I don't know when it decides to do that, but most other browsers would be still displaying your splash screen while FF2 has hidden it and has stuff dancing about on the screen.

OTOH, if you widget is not attached and you are setting percentage heights and widths, for example, they will fail.

Ian

Arthur Kalmenson

unread,
Apr 16, 2009, 10:55:47 AM4/16/09
to Google-We...@googlegroups.com
Just asked a GWT wizard on IRC and turns out I was incorrect. He
offered an interesting alternative solution. Build the table as HTML
and send that down instead.

--
Arthur Kalmenson

Vitali Lovich

unread,
Apr 16, 2009, 11:00:31 AM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 10:46 AM, Ian Bambury <ianba...@gmail.com> wrote:
2009/4/16 Vitali Lovich <vlo...@gmail.com>


You seem to be saying that:

tree t = new tree()
t.addItem("abc");
t.addItem("def");
RootPanel.get().add(t);

will have fewer reflows than

tree t = new tree()
RootPanel.get().add(t)
t.addItem("abc")
t.addItem("def")

According to you (at least from what you've said so far) is that the 1st snippet will cause 1 DOM reflow whereas the below snippet will cause 2, which isn't actually the case AFAIK.  Both will only cause 1 & will be equally fast.

I think you are both right, depending on the browser you are in.

FF2 (IIRC) will rerender during a sequence where most other browsers won't. I don't know when it decides to do that, but most other browsers would be still displaying your splash screen while FF2 has hidden it and has stuff dancing about on the screen.
No, even FF2 should display the same behaviour.  There's only two ways (at least that I can see) that the browser could reflow DOM changes as they are being performed within Javascript.

1)  Have a secondary thread performing the rendering.  This might actually be a performance improvement that browser vendors could look at, but it makes it really difficult because then you have to introduce synchronization particularly since rendering can actually change the DOM AFAIK.  But even if it couldn't there would be other thread-safety related issues.  No browser AFAIK actually does this.

2)  Perform reflows as the underlying DOM is manipulated via JS.   This would be bad from a performance perspective (we want to minimize reflows which would not be possible if we couldn't merge multiple DOM manipulations into 1 reflow being triggered).  It may also be difficult from an architectural perspective depending on how JS manipulations of the DOM are implemented (it probably bypasses a lot of code & manipulates the raw data structures).

Vitali Lovich

unread,
Apr 16, 2009, 11:10:40 AM4/16/09
to Google-We...@googlegroups.com
I dunno about that one two fronts:

1)  All the same DOM elements still have to be created.  This would only help if you have such a slow JS engine in your browser that running the DOM manipulations in Javascript is so slow that it outweighs the cost of actually performing the manipulations (which I believe would always be done in native code anyways)

2)  You're transmitting more data across the pipe - the extra markup is unnecessary data & can bloat your transfer by quite a bit, slowing down your responsiveness.

3)  It's not scalable.  Your moving rendering code from the client to the server which places more load on the server.  Performing string concatenations also isn't cheap (unless you build your own string class that offers fast concatenation through pointers to strings & perform all the stream output yourself).  Obviously if the number of users is limited you don't care.

So all 3 reasons together (mainly 1 & 2 though), I don't see how that would help.  Obviously some hard numbers are needed as all this is just hand waving guesses of expected behaviour.

Jason Essington

unread,
Apr 16, 2009, 11:19:30 AM4/16/09
to Google-We...@googlegroups.com
You might want to tell the Lombardi Blueprint guys that ... as it turns out, they discovered in the development of their application that you are mistaken on all points.

Feel free to watch their presentation from Google I/O last year if you'd like to check my references:

-jason

Vitali Lovich

unread,
Apr 16, 2009, 11:44:09 AM4/16/09
to Google-We...@googlegroups.com
Can you point out the relevant segments within the presentation?  I skimmed through some parts, & it seemed like they went for just building the raw HTML on the client side (hence the reason they transfer HTML from the server).

Also, they're presentation is for 1.4, so they're reasons might not be relevant any more (especially since 1.5 included a lot of improvements & 1.6 introduced improvements with the event subsystem).

Also, they don't seem to be using deferred binding for some reason to get around

Jason Essington

unread,
Apr 16, 2009, 12:04:18 PM4/16/09
to Google-We...@googlegroups.com
Their reasoning was that object instantiation was orders of magnitude slower than simply building the HTML. in some cases even building HTML on the client was too slow, so they would shuttle it off to the server. The application would decide at runtime which way was faster, and use the fastest method.

For a quick rendering test, you can try to create a 100x100 table (grid) using GWT widgets, and then do the same thing using setInnerHTML() (with a string that ultimately has the same DOM) ... you'll find that while the setInnerHTML() is nearly instantaneous, the creation of the widgets takes some time.

Creation of individual DOM elements in javascript seems to be pretty slow (it is a bit faster in the new generation browsers ff3, Safari4 and chrome) but setInnerHTML() doesn't create those elements in javascript, it is done natively in the browser and thus is much faster.

Another technique that I use when populating multiple "cells" that have the same HTML structure is to embed a hidden "template" in the host page. This template has all of the HTML structure, but no content. I have GWT find and store the elements that will be bound with data (traverse the DOM of the template only once) from my model objects, then when I need to fill the cells, I setInnerText, or setInnerHTML() on each of the found elements from the template, and once the databinding is complete, perform a getInnerHTML() on the template, and use that string to setInnerHTML() on the "cell" ... this works great as there is really no DOM object creation happening in Javascript, and is considerably faster than building up the widgets individually.


-jason

Thomas Broyer

unread,
Apr 16, 2009, 12:08:58 PM4/16/09
to Google Web Toolkit
3. Well, I pointed to John Resig's experiment with DocumentFragment,
and it's something that I've seen repeated in several presentations
about performance of "DHTML" applications. Here are some links I
gathered some time ago:
http://www.slideshare.net/julien.lecomte/high-performance-ajax-applications
http://www.slideshare.net/pureclone/highperformance-javascript

See also:
http://www.slideshare.net/iamtin/speed-of-ajax-presentation (slide 27)
See also this, that I've just stumbled upon:
http://stackoverflow.com/questions/544180/does-visibility-affect-dom-manipulation-performance

4. Not a benchmark either, but this affirmation by Microsoft:
http://msdn.microsoft.com/en-us/library/ms531161(VS.85).aspx

Vitali Lovich

unread,
Apr 16, 2009, 12:55:17 PM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 12:04 PM, Jason Essington
<jason.e...@gmail.com> wrote:
> Their reasoning was that object instantiation was orders of magnitude slower
> than simply building the HTML. in some cases even building HTML on the
> client was too slow, so they would shuttle it off to the server. The
> application would decide at runtime which way was faster, and use the
> fastest method.
> For a quick rendering test, you can try to create a 100x100 table (grid)
> using GWT widgets, and then do the same thing using setInnerHTML() (with a
> string that ultimately has the same DOM) ... you'll find that while the
> setInnerHTML() is nearly instantaneous, the creation of the widgets takes
> some time.
It really depends on what you're trying to do isn't it. If you have a
static grid that you populate, why would you ever be modifying the DOM
structure? You just create your grid to begin with & then simply
iterate over the widgets & set the data. You also get the added
benefit that your code is far more flexible & maintainable (you don't
have to worry about introducing typos in your HTML generator).

If you have a dynamic UI then maybe it might be more advantageous, but
then again those tend to use absolute positioning which means DOM
modifications do not cause a reflow (only a repaint).

> Creation of individual DOM elements in javascript seems to be pretty slow
> (it is a bit faster in the new generation browsers ff3, Safari4 and chrome)
> but setInnerHTML() doesn't create those elements in javascript, it is done
> natively in the browser and thus is much faster.
I'd need to see a benchmark that that is indeed the case. I don't
have time right now (I'll experiment later if I have the chance). But
it seems wrong that creating the DOM elements in javascript is slower
than having the browser do it natively (the cost of modifying the DOM
should be the dominant factor by far).

> Another technique that I use when populating multiple "cells" that have the
> same HTML structure is to embed a hidden "template" in the host page. This
> template has all of the HTML structure, but no content. I have GWT find and
> store the elements that will be bound with data (traverse the DOM of the
> template only once) from my model objects, then when I need to fill the
> cells, I setInnerText, or setInnerHTML() on each of the found elements from
> the template, and once the databinding is complete, perform a getInnerHTML()
> on the template, and use that string to setInnerHTML() on the "cell" ...
> this works great as there is really no DOM object creation happening in
> Javascript, and is considerably faster than building up the widgets
> individually.
How is this different than building up the HTML structure using
widgets as I mention above?

Jason Essington

unread,
Apr 16, 2009, 12:59:04 PM4/16/09
to Google-We...@googlegroups.com
No widget baggage ...

Vitali Lovich

unread,
Apr 16, 2009, 1:13:40 PM4/16/09
to Google-We...@googlegroups.com
Which is arguably worse. You'd have to convince me that your app is
so super optimized that the memory overhead of using widgets is really
costing you. If it's CPU bottlenecked, you'd have to convince me that
there's absolutely no room for improvement using caching techniques &
whatnot.

The widgets save so much on development efforts. First of all,
refactoring is trivial & won't break anything. It's trivial to build
up new, complex* widgets using the framework & you don't have to worry
about breaking your HTML generator. You don't need to assign unique
ids to every single widget so that you can access them. The API for
modifying widgets is far easier & more extensible to use than building
up the HTML from scratch.

* Even something as simple as event handling becomes a complete mess
(& you're also breaking the paradigm of GWT meaning you can now
introduce memory leaks if you're not careful).

Jason Essington

unread,
Apr 16, 2009, 1:22:28 PM4/16/09
to Google-We...@googlegroups.com
oops, my bad, you are talking about the grid example ...

This is overly simplified, but ...

Well lets look at what is happening. every time you create a widget,
you instantiate a javascript object, that object has fields and
methods to support widget behavior, so more javascript object
instantiation, you also call Document.createElement() to create the
element that will ultimately be inserted into the DOM ... now you do
this multiple times because composite widgets are rarely just a single
widget. All of this stuff is done in an interpreted dynamic language ...

Now, getInnerHtml() -> setInnerHTML() no objects are created in
javascript, (well, ok one string is created by the getInnerHTML call)
a single DOM method call is made that passes text to the underlying
browser rendering engine (usually compiled C of some sort) that engine
renders the html and you are done.

Though there have been great strides in Javascript engine performance
in the last year, they still are nowhere near the performance of
compiled C code.

-jason


On Apr 16, 2009, at 10:55 AM, Vitali Lovich wrote:

Pascal

unread,
Apr 16, 2009, 1:27:01 PM4/16/09
to Google Web Toolkit
> > Creation of individual DOM elements in javascript seems to be pretty slow
> > (it is a bit faster in the new generation browsers ff3, Safari4 and chrome)
> > but setInnerHTML() doesn't create those elements in javascript, it is done
> > natively in the browser and thus is much faster.
>
> I'd need to see a benchmark that that is indeed the case.  I don't
> have time right now (I'll experiment later if I have the chance).  But
> it seems wrong that creating the DOM elements in javascript is slower
> than having the browser do it natively (the cost of modifying the DOM
> should be the dominant factor by far).

Seriously, this is not even close. In IE for a table as small as 50
rows with 15 columns, you're looking at a few seconds with the DOM and
below 100ms with innerHTML. (on a dev laptop here anyway).

Jason Essington

unread,
Apr 16, 2009, 1:30:14 PM4/16/09
to Google-We...@googlegroups.com
This is absolutely true, but we are not talking about day to day GWT
development, we are talking about extraordinary circumstances where
some amount of optimization is needed.

Under every normal circumstance you would simply develop using
widgets, but that becomes impossible if some use case says you need to
fill a 100,000 cell grid all at once. That sort of thing puts you into
a position where normal GWT development techniques just aren't able to
do the job.

If you are simply displaying (read only) data, there may be no reason
to add all the overhead of a heavyweight object like a widget, and
straight html may be the better option.

-jason

Vitali Lovich

unread,
Apr 16, 2009, 2:08:40 PM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 1:30 PM, Jason Essington
<jason.e...@gmail.com> wrote:
>
> This is absolutely true, but we are not talking about day to day GWT
> development, we are talking about extraordinary circumstances where
> some amount of optimization is needed.
I'm still not convinced that falling back to raw HTML & inserting it
onto the page is the right answer - I'm confident there would be a way
around it. Of course, I've never built a GWT app that tries to put a
lot of widgets on the page, so I have no experience here (just
conjecture).

>
> Under every normal circumstance you would simply develop using
> widgets, but that becomes impossible if some use case says you need to
> fill a 100,000 cell grid all at once. That sort of thing puts you into
> a position where normal GWT development techniques just aren't able to
> do the job.
But the question should be as follows:
1) Do I need to actually draw all 100 000 widgets at once? Can I
display a portion of the data & defer the rest for a later point in
time (perhaps doing it in the background)
2) Why am I constantly recreating the widget structure instead of
doing it once and simply changing the data displayed.

>
> If you are simply displaying (read only) data, there may be no reason
> to add all the overhead of a heavyweight object like a widget, and
> straight html may be the better option.
meh - at that point why even bother with GWT? you're better off just
serving up the HTML using regular Java servlets or PHP (unless you're
getting HTML data from a third-party, in which case obviously it makes
sense to use the raw HTML since there's no point in trying to parse
it).

Vitali Lovich

unread,
Apr 16, 2009, 2:14:53 PM4/16/09
to Google-We...@googlegroups.com
Me thinks there might a problem with your testing methodology. First
I think you're not taking into account the building of the string
whereas you do time the widget creation. Secondly, if you have a
constant 50 rows & 15 columns, see how long it takes to set the data
once you've pre-created your widgets (this should actually be faster I
think than innerHTML if you have HTML elements there).
Thirdly IE is the slowest browser (Javascript is actually notoriously
slower - not sure about DOM, but even that is still slower than any
other browser). At least tell me you're testing with IE7 (which is
still what, 2x slower than FF3.0 & 5 times slower than FF3.5).
Fourthly, I'd prefer to use something like Firebug's profiling rather
than trying to instrument my own code - it's far less likely you'll
make a mistake or misinterpret the data I think.

> >
>

Arthur Kalmenson

unread,
Apr 16, 2009, 2:15:41 PM4/16/09
to Google-We...@googlegroups.com
> 1) Do I need to actually draw all 100 000 widgets at once? Can I
> display a portion of the data & defer the rest for a later point in
> time (perhaps doing it in the background)

You can do that with IncrementalCommand, but at the end of the day
you're still going to choke the browser each time this needs to be
displayed.

> 2) Why am I constantly recreating the widget structure instead of
> doing it once and simply changing the data displayed.

That's fine, but you still need to create the widget and that's
what'll take a lot of time. If it takes 20 seconds to log into your
application because you're generating the grid in the background,
that's not going to make your users happy.

> meh - at that point why even bother with GWT? you're better off just
> serving up the HTML using regular Java servlets or PHP (unless you're
> getting HTML data from a third-party, in which case obviously it makes
> sense to use the raw HTML since there's no point in trying to parse

You're doing all of this asynchronously with XHRs, making it nice and sexy.

--
Arthur Kalmenson

Vitali Lovich

unread,
Apr 16, 2009, 2:26:51 PM4/16/09
to Google-We...@googlegroups.com


On Thu, Apr 16, 2009 at 1:22 PM, Jason Essington <jason.e...@gmail.com> wrote:
>
> oops, my bad, you are talking about the grid example ...
>
> This is overly simplified, but ...
>
> Well lets look at what is happening. every time you create a widget,
> you instantiate a javascript object, that object has fields and
> methods to support widget behavior, so more javascript object
> instantiation, you also call Document.createElement() to create the
> element that will ultimately be inserted into the DOM ... now you do
> this multiple times because composite widgets are rarely just a single
> widget. All of this stuff is done in an interpreted dynamic language ...
This is only bad with a crappy interpreter.  Seriously, Webkit, Gecko & Presto just cream IE7 (IE8 numbers don't seem to be available, but I don't hold much hope) & the new iterations are several times faster than that.

In fact, it appears that aside from IE, DOM is actually faster* than innerHTML

* Caveat - I don't endorse the testing methodology because I haven't reviewed it, so it may be bunk.  Nevertheless, it does appear that the common wisdom of using innerHTML may be a holdover.  Now obviously widgets are more heavyweight than the DOM manipulations he's using, so I'm not sure what the impact of that is.


>
> Now, getInnerHtml() -> setInnerHTML() no objects are created in
> javascript, (well, ok one string is created by the getInnerHTML call)
> a single DOM method call is made that passes text to the underlying
> browser rendering engine (usually compiled C of some sort) that engine
> renders the html and you are done.
>
> Though there have been great strides in Javascript engine performance
> in the last year, they still are nowhere near the performance of
> compiled C code.
Depends on what you're doing.  I'm pretty sure that the overhead of parsing HTML in C is far greater than simply modifying a few pointers here or there in JS.

Vitali Lovich

unread,
Apr 16, 2009, 2:31:02 PM4/16/09
to Google-We...@googlegroups.com
On Thu, Apr 16, 2009 at 2:15 PM, Arthur Kalmenson <arthu...@gmail.com> wrote:

>   1)  Do I need to actually draw all 100 000 widgets at once?  Can I
> display a portion of the data & defer the rest for a later point in
> time (perhaps doing it in the background)

You can do that with IncrementalCommand, but at the end of the day
you're still going to choke the browser each time this needs to be
displayed.
Well obviously you don't insert into the DOM.  In THIS case, you build your widgets detached in incremental steps (maybe doing 100-500 milliseconds worth of processing each time).  Once you're done, you attach the whole enchileda to the page.

This actually becomes even easier with worker threads.


>   2)  Why am I constantly recreating the widget structure instead of
> doing it once and simply changing the data displayed.

That's fine, but you still need to create the widget and that's
what'll take a lot of time. If it takes 20 seconds to log into your
application because you're generating the grid in the background,
that's not going to make your users happy. 
Use the incremental thing above, & you won't.  If applicable, you can also bury the "expensive" UI deeper in the navigation so that while the user is navigating to it, you're creating it in the background (obviously you don't make it redundantly deep - just hopefully it'll be in a natural location that doesn't need to be visible right away).

Vitali Lovich

unread,
Apr 16, 2009, 2:34:31 PM4/16/09
to Google-We...@googlegroups.com
Also wanted to add that while innerHTML will get faster only incrementally, the DOM approach actually benefits from the VM getting faster (which is where all the focus is on optimization these days).

Pascal

unread,
Apr 16, 2009, 5:09:05 PM4/16/09
to Google Web Toolkit
A bit in denial are we? Here are raw numbers for you.

http://www.quirksmode.org/dom/innerhtml.html

YO

Pascal

unread,
Apr 16, 2009, 5:10:32 PM4/16/09
to Google Web Toolkit
Sorry, post sent by mistake

YO was meant to be
You don't even need to trust my testing methodology.

:-)

Vitali Lovich

unread,
Apr 16, 2009, 6:08:59 PM4/16/09
to Google-We...@googlegroups.com
I dunno, I don't see anywhere near the difference the website claims (average over 5 runs):

on Q6600 @ 3.2 GHz
FF 3.5 b4:

DOM1 65 ms
DOM2 65 ms
Table 69 ms
Inner1: 37 ms
Inner2: 39 ms

FF 3.0.8

DOM1 86 ms
DOM2 73 ms
Table 80 ms
Inner1: 43 ms
Inner2: 42 ms

Konqueror (don't have chrome or safari, but KHTML should be fairly close to Webkit)
DOM1 25 ms
DOM2 21 ms
Table 24 ms
Inner1: 15 ms
Inner2: 16 ms

On my laptop (Turion x64 @ 2.2 GHz)

DOM1 125 ms
DOM2 112 ms
Table 141 ms
Inner1: 83 ms
Inner2: 80 ms

So the DOM is slower in this test*, but not as significantly as Arthur claimed (1.5x as opposed to 10-30x.  However, considering the amount of flexibility that is lost when building the HTML yourself, I don't think it's justified.

* Again not approving the methodology necessarily since I haven't actually looked at what it does exactly.  It has nothing to do with who writes it but whether or not I understand what the test is doing & I think it's doing a valid comparison (i.e. an objective metric).

One thing I can think off the bat is that the way this code is written, innerHTML can never lose.  But it doesn't represent the test case that was presented (or even a realistic one).  Consider this situation:  instead of setting just to a simple character (or simple text) `*', use a slightly more complex HTML layout.

<div class="foo">this is a <div id="abc" class="bar">complex</div> inner HTML example<img src="some raw base 64 image"</img></div>.

Also, to make it more realistic, have random values set for complex so that you have to generate the string randomly each time.  I'm quite confident that you'll see, all of a sudden, DOM & probably GWT widgets, show no performance difference whereas the innerHTML will get more expensive (slower than using DOM or GWT).  I'll write a test case sometime later if I feel like it.

Again all of this excludes IE which is a crap browser when it comes to standards or performance.  I"m on Linux, so I can't test the other browsers (don't feel like rebooting).

Jason Essington

unread,
Apr 16, 2009, 6:23:25 PM4/16/09
to Google-We...@googlegroups.com
You'll also want to note that 50x50 is a pretty small test grid compared to what we were talking about here, when the size grows, the time it takes isn't necessarily linear for the DOM object creation.

but I've got to say, the results are not what I would have expected on my machine with Safari 4!

2.66ghz MacPro with Safari 4

DOM 1: 7 ms
DOM 2: 8 ms
Table: 8 ms
inner1: 16 ms
inner2: 16 ms

Firefox 3.0.8 is pitifully slow in comparison
DOM 1: 88 ms
DOM 2: 74 ms
Table: 90 ms
inner1: 36 ms
inner2: 34 ms

looks like Safari's new javascript engine is pretty damn zippy at creating DOM objects! who would have guessed?

-jason

Vitali Lovich

unread,
Apr 16, 2009, 6:42:07 PM4/16/09
to Google-We...@googlegroups.com
No it's not necessarily linear (although I expect that it is actually fairly linear).  But I think you're missing the larger point which is that the performance is going to be extremely similar since you're only going to create the grid once with DOM (1.5x isn't that much & as you can see, a faster JS engine can actually make the DOM faster).

innerHTML is not inherently faster - I'd argue it's inherintley slower, we just had (unnecessarily) crappy JS performance historically (thank you Apple & Google for really lighting a fire under everyone).  I think there's still room for improvement - there's no reason JS performance can't approach native or even surpass like Java does (except for the initial overhead of parsing & compiling the JS).

For that though I think GWT is perfectly positioned because it's cached per-browser js can be compiled by the browser into an intermediary form & cached until a new version of the app is available.

As has been shown, JIT for javascript is still at the early stages - there's still large performance gains to be had.

Arthur Kalmenson

unread,
Apr 16, 2009, 6:43:31 PM4/16/09
to Google-We...@googlegroups.com
I think the main question is how it perform in the various IEs. That's
the browser you'll see 70% in the wild and 100% of the time in most
corporate environments.

--
Arthur Kalmenson

ytbryan

unread,
Apr 25, 2009, 10:05:18 PM4/25/09
to Google Web Toolkit
thank you for all replies.

i have a few questions:

1) JSON data graph with Javascript Overlay -- i can't find example on
this... can someone tell me what is this?

2) so the rendering of the data is probably the reason why an
application looks slow..... if the data i want to transfer from
server to client is huge..... should i still be using RPC? or is there
a better method? currently, i am using gwt-rpc to transfer 2d array of
string.....

3 can someone explain to me why the need of JSON and XMl
serialisation? besides the need to communicate with non-java server?


thanks......
> > On Thu, Apr 16, 2009 at 11:19 AM, Jason Essington <jason.essing...@gmail.com
> > > wrote:
> > You might want to tell the Lombardi Blueprint guys that ... as it  
> > turns out, they discovered in the development of their application  
> > that you are mistaken on all points.
>
> > Feel free to watch their presentation from Google I/O last year if  
> > you'd like to check my references:
> >http://sites.google.com/site/io/using-gwt-to-build-a-high-performance...
>
> > -jason
>
> > On Apr 16, 2009, at 9:10 AM, Vitali Lovich wrote:
>
> >> I dunno about that one two fronts:
>
> >> 1)  All the same DOM elements still have to be created.  This would  
> >> only help if you have such a slow JS engine in your browser that  
> >> running the DOM manipulations in Javascript is so slow that it  
> >> outweighs the cost of actually performing the manipulations (which  
> >> I believe would always be done in native code anyways)
>
> >> 2)  You're transmitting more data across the pipe - the extra  
> >> markup is unnecessary data & can bloat your transfer by quite a  
> >> bit, slowing down your responsiveness.
>
> >> 3)  It's not scalable.  Your moving rendering code from the client  
> >> to the server which places more load on the server.  Performing  
> >> string concatenations also isn't cheap (unless you build your own  
> >> string class that offers fast concatenation through pointers to  
> >> strings & perform all the stream output yourself).  Obviously if  
> >> the number of users is limited you don't care.
>
> >> So all 3 reasons together (mainly 1 & 2 though), I don't see how  
> >> that would help.  Obviously some hard numbers are needed as all  
> >> this is just hand waving guesses of expected behaviour.
>
> >> On Thu, Apr 16, 2009 at 10:55 AM, Arthur Kalmenson <arthur.k...@gmail.com
> >> > wrote:
>
> >> Just asked a GWT wizard on IRC and turns out I was incorrect. He
> >> offered an interesting alternative solution. Build the table as HTML
> >> and send that down instead.
>
> >> --
> >> Arthur Kalmenson
>
> >> On Thu, Apr 16, 2009 at 10:46 AM, Ian Bambury  
> >> <ianbamb...@gmail.com> wrote:
> >> > 2009/4/16 Vitali Lovich <vlov...@gmail.com>

Vitali Lovich

unread,
Apr 26, 2009, 5:17:59 PM4/26/09
to Google-We...@googlegroups.com
On Sat, Apr 25, 2009 at 10:05 PM, ytbryan <ytb...@gmail.com> wrote:

thank you for all replies.

i have a few questions:

1) JSON data graph with Javascript Overlay -- i can't find example on
this... can someone tell me what is this?
not sure what you mean here.  What data graph?  Coding basics is very useful - has a good introduction to overlay objects.


2) so the  rendering of the data is probably the reason why an
application looks slow.....
never make assumptions about performance.  profile your application & get hard numbers.  there's several reasons to do this, 2 are extremely important.  1) You are not making guesses - you know exactly where the problem is in your code.  2)  You know if your optimizations actually make something faster or slower.
 
 if the data i want to transfer from
server to client is huge..... should i still be using RPC? or is there
a better method? currently, i am using gwt-rpc to transfer 2d array of
string.....
It depends.  RPC is very good & more importantly, it's extremely convenient to use.  If the bottleneck is really the deserialization or the transferred data is too big, you may want to serialize to JSON instead & then just eval on the client side & cast it to an overlay object - that'll definitely be faster in terms of deserialization performance, and may be smaller in terms of transfer size.  However, the server impact is much harder to estimate - there are too many factors.  It could improve performance, make it worse, or have no impact.


3 can someone explain to me why the need of JSON and XMl
serialisation? besides the need to communicate with non-java server?
Not sure what you mean here.  JSON & XML data sources are very common on the internet.  Many web-apps use services & data stores on third-party servers (i.e. Google maps).  Since google likes people building things on top of their services, building it into GWT is nice (although adding this functionality is not difficult since the browsers support it natively).

ytbryan

unread,
Apr 28, 2009, 7:09:26 AM4/28/09
to Google Web Toolkit
ok... thank you for your reply Vitali.

:)

On Apr 26, 11:17 pm, Vitali Lovich <vlov...@gmail.com> wrote:
> On Sat, Apr 25, 2009 at 10:05 PM, ytbryan <ytbr...@gmail.com> wrote:
>
> > thank you for all replies.
>
> > i have a few questions:
>
> > 1) JSON data graph with Javascript Overlay -- i can't find example on
> > this... can someone tell me what is this?
>
> not sure what you mean here.  What data graph?  Coding
> basics<http://code.google.com/webtoolkit/doc/1.6/DevGuideCodingBasics.html>is
Reply all
Reply to author
Forward
0 new messages