GWT and large applications

10 views
Skip to first unread message

Sanjiv Jivan

unread,
Feb 29, 2008, 10:30:58 AM2/29/08
to Google Web Toolkit Contributors
Hi,
I realize this topic has been brought up several times, and the
general suggestion from GWT is to split the application into separate
modules and use iframes.

While this is a workable solution, I feel that GWT can do a little
better to support large apps by allowing users to split their
application into separate modules, however instead of having these
separate modules be treated as separate apps loading in iframe, be
aware that these modules belong to the same application and have he
ability to lazy load these separate modules as JS only, without the
boilerplate GWT stuff that does into each compiled application. There
can be some inherits type contract to indicate that a module is only
part of the main app.

Each of these JS only modules load in the the context of the main app,
without requiring a separate iframes or and repeated shared code as
would be the case if these were loaded as separate apps in iframes.

I feel this approach has several advantages over the iframe approach

- as mentioned above, there is not repeated boiler plated code
- seamlessly works as a single app, where portions of the apps (i.e
the separate modules) are transparently loaded in chunks. Once loaded,
it is equivalent to the the whole all being loaded as a single JS GWT
can still behind the scenes to a MD5 check to see if JS module needs
to be refetched. With the iframe approach, there will be a "blank"
screen during the period a request to a new module is made
- related to the point above, application functions as a single app,
and not an integration solution. things like SSO work better.

Any thoughts or comments?

Thanks,
Sanjiv

GWT-Ext Widget Library : http://code.google.com/p/gwt-ext/




Bruce Johnson

unread,
Feb 29, 2008, 10:48:13 AM2/29/08
to Google-Web-Tool...@googlegroups.com
I think the right way to model this isn't to treat lazy-loaded pieces as separate modules, but instead to think of it as on-demand loading of coarse-grained chunks of a single module. The reason you want it to be one module is for optimization reasons: you can optimize a lot more when you compile things monolithically. Also, because a compiled module serves as a namespace for obfuscated identifiers, so to have tight Java-level integration among objects, they need to be obfuscated the same way. Think of each module as sibling Java class loaders. You can't actually share objects -- even those of the same class -- if they were created in different sibling class loaders. That's analogous to the effect of obfuscating separate modules independently: you can pass objects of the same class between them, but they appear to be totally foreign (because their identifiers are almost certainly obfuscated differently).

We've discussed an idea that goes like this:

  GWT.createAsync(SomeClassThatCanBeLoadedLazily.class, new AsyncCallback() { ... });

The compiler could then split your module apart into chunks, using the createAsync() calls as hints as to where you'd be willing to let you app be split up into lazily-loaded islands of classes.

We should recognize that there are really two totally separate issues at play here, though:
(1) My app is genuinely too big, and it strains the limits of what a browser can handle in a single page (e.g. too many elements, too much GC pressure).
(2) I want my app to start as fast as possible, and only load rarely-used features lazily.

In the case of #1, there's no alternative to the approach we've always recommended: you have to break it up into separate pages and use history to smooth other the transitions. (BTW, I've not yet seen an app that has unequivocally necessitated this kind of partitioning, which is why we also tell people, "You don't need to worry about this as much as you fear. Just put everything into one module.")

In the case of #2, it's really just an optimization. And that's the angle we're interested in investigating . And, philosophically, you're right that we should strive to ensure that the separately-loaded parts are as integrated as possible for the best user experience.

-- Bruce

Sanjiv Jivan

unread,
Feb 29, 2008, 11:02:12 AM2/29/08
to Google Web Toolkit Contributors
Hi Bruce,
I used the term (sub) module loosely, but coarse-grained chunks of a
single module is what I was talking about.

And this would be to address your second use-case "(2) I want my app
to start as fast as possible, and only load rarely-used features
lazily."

If you have a look at the smartclient demo application, you'll see
that this is the approach they've taken and it allows for a really
nice user experience as a large app also loads really fast. Portions
of their app are loaded lazily on first access.

I forgot to mention that this approach also is a lot more offline
friendly. It would be great if GWT can also incorporate a mechanism to
globally turn of lazy loading of application chunks, or a way to force
all lazy chunks to be eagerly loaded. This would very useful when
using Gears.

Thanks,
Sanjiv

GWT-Ext Widget Library : http://code.google.com/p/gwt-ext/

> On Fri, Feb 29, 2008 at 10:30 AM, Sanjiv Jivan <sanjiv.ji...@gmail.com>

John Tamplin

unread,
Feb 29, 2008, 11:07:58 AM2/29/08
to Google-Web-Tool...@googlegroups.com
On Fri, Feb 29, 2008 at 10:30 AM, Sanjiv Jivan <sanjiv...@gmail.com> wrote:
I feel this approach has several advantages over the iframe approach

- as mentioned above, there is not repeated boiler plated code

The problem is that the "boiler plate" code is not actually the same, since it is optimized to the code that goes into the module.  For example, if someplace an Object is used in the source (say for example, a raw HashMap or HashMap<Object,...>) is only ever called with a String, then it will be treated as String and be inlined with native JS String constructs.  Once you allow dynamically loaded modules that aren't part of the current module, all of that optimization has to go out the window, and dead-stripping of code as well.
 
- seamlessly works as a single app, where portions of the apps (i.e
the separate modules) are transparently loaded in chunks. Once loaded,
it is equivalent to the the whole all being loaded as a single JS GWT
can still behind the scenes to a MD5 check to see if JS module needs
to be refetched. With the iframe approach, there will be a "blank"
screen during the period a request to a new module is made

Java calls are synchronous, so when you call a method you don't have a way of returning control to the browser.  However, synchronous loading of JS means blocking the entire UI of the browser while you wait on the code to get loaded.  Also, what do you do in the case of errors?  The point of Bruce's suggestion of GWT.createAsync is it creates a boundary where the code knows that the module is to be loaded, and has a callback for when it is ready or if an error occured.
 
- related to the point above, application functions as a single app,
and not an integration solution. things like SSO work better.

Unless I misunderstand, the point of SSO is to allow several apps to seamlessly share the same authentication domain and credentials, so in fact you having multiple modules is totally seamless if you are using SSO.  I will agree that if you have a simple authentication system splitting the app into multiple modules will force SSO.

--
John A. Tamplin
Software Engineer, Google

Sanjiv Jivan

unread,
Feb 29, 2008, 11:25:42 AM2/29/08
to Google Web Toolkit Contributors
Hi John,

On Feb 29, 11:07 am, "John Tamplin" <j...@google.com> wrote:
> On Fri, Feb 29, 2008 at 10:30 AM, Sanjiv Jivan <sanjiv.ji...@gmail.com>
> wrote:
>
> > I feel this approach has several advantages over the iframe approach
>
> > - as mentioned above, there is not repeated boiler plated code
>
> The problem is that the "boiler plate" code is not actually the same, since
> it is optimized to the code that goes into the module. For example, if
> someplace an Object is used in the source (say for example, a raw HashMap or
> HashMap<Object,...>) is only ever called with a String, then it will be
> treated as String and be inlined with native JS String constructs. Once you
> allow dynamically loaded modules that aren't part of the current module, all
> of that optimization has to go out the window, and dead-stripping of code as
> well.
>

I was referring to "coarse-grained chunks of a single module" rather
than a typical GWT module.


> > - related to the point above, application functions as a single app,
> > and not an integration solution. things like SSO work better.
>
> Unless I misunderstand, the point of SSO is to allow several apps to
> seamlessly share the same authentication domain and credentials, so in fact
> you having multiple modules is totally seamless if you are using SSO. I
> will agree that if you have a simple authentication system splitting the app
> into multiple modules will force SSO.

I did not word that correctly. The point I was trying to make was that
for a single (large) app, SSO between portions of the "coarse-grained
chunks" should not be required. With the iframe recommendation for
large apps, one may need to implement a SSO solution as each module of
the large app is essentially loaded as a separate app and this
complicated the overall solution. Many app have the notion of a
session and authenticated user, and the business logic of the app is
based on the context of the "current user". With the iframe solution,
this becomes problematic as the sessions are not shared. With the lazy
load of JS chunks, this will be a non-issue. Hope this clarifies.

evaleto genebio

unread,
Feb 29, 2008, 11:34:38 AM2/29/08
to Google-Web-Tool...@googlegroups.com
(resend with correct email)

Hi,
I implemented a solution for dynamic modules loading on runtime
without iframe and with a basic events framework to interact between modules.

There is a basic sample application here:
http://downloads.phenyx-ms.com/olivier/

You can look the html source, you will see 3 gwt modules, each gwt modules is
instanced on a tab and one module catch event from the *Panel* module.
As you can see, obfuscated code can be plugged together. Of course,
you lazy load modules.

If some one is interested, I'll see to publish the code and wiki ASAP.

Regards,
Olivier

2008/2/29, Sanjiv Jivan <sanjiv...@gmail.com>:

stuckagain

unread,
Mar 3, 2008, 4:06:49 AM3/3/08
to Google Web Toolkit Contributors
Hi,

I would be interested in the code... are you adding applications
dynamically or are they all references from the HTML statically ?
Getting it to work statically is not that hard, but adding GWT
applications dynamically is currently not possible (as far as I know,
due the way the generated JS file starts a GWT application (using
document.write to load other JS files).

David

On Feb 29, 5:34 pm, "evaleto genebio" <evaleto.gene...@gmail.com>
wrote:
> (resend with correct email)
>
> Hi,
> I implemented a solution for dynamic modules loading on runtime
> without iframe and with a basic events framework to interact between modules.
>
> There is a basic sample application here:http://downloads.phenyx-ms.com/olivier/
>
> You can look the html source, you will see 3 gwt modules, each gwt modules is
> instanced on a tab and one module catch event from the *Panel* module.
>  As you can see, obfuscated code can be plugged together. Of course,
> you lazy load modules.
>
> If some one is interested, I'll see to publish the code and wiki ASAP.
>
> Regards,
> Olivier
>
> 2008/2/29, Sanjiv Jivan <sanjiv.ji...@gmail.com>:
> >  GWT-Ext Widget Library :  http://code.google.com/p/gwt-ext/- Hide quoted text -
>
> - Show quoted text -

stuckagain

unread,
Mar 3, 2008, 4:14:00 AM3/3/08
to Google Web Toolkit Contributors
Hi,

Well nice to hear the subject is still alive :-)

All I would like to be able to do in GWT is to load multiple GWT
applications in one HTML document and let them interact.

The use case is not about optimisation but about multiple applications
being developped and deployed in a generic GWT framework, a bit
similar to iGoogle. So it is not feasable to have one big uber
application.

The IFrames are a very bad choice:
- Memory leaks (I posted a bug about this, including a fix, but nobody
seems to care about it)
- Memory usage: when I have 10 IFrames open IE uses about 100MB and
every clicks starts taking 5-10 seconds to handle.
- IFrame support in GWT is very limited (due to technical problems I
understand), for example onclick, focus/blur is not supported and as a
consequence dialogs and menubars do not disappear when clicking on the
IFrames.

Sanjiv Jivan

unread,
Mar 4, 2008, 6:45:50 PM3/4/08
to Google Web Toolkit Contributors
This is precisely what I was trying to describe :
http://glinden.blogspot.com/2008/01/optimizing-web-20-applications.html

Bruce, any idea when more details about the GWT.createAsync strategy
will be available, and it there's a targeted release for this feature.

Thanks,
Sanjiv

On Feb 29, 10:48 am, "Bruce Johnson" <br...@google.com> wrote:
> On Fri, Feb 29, 2008 at 10:30 AM, Sanjiv Jivan <sanjiv.ji...@gmail.com>

John Tamplin

unread,
Mar 4, 2008, 6:58:19 PM3/4/08
to Google-Web-Tool...@googlegroups.com
On Tue, Mar 4, 2008 at 6:45 PM, Sanjiv Jivan <sanjiv...@gmail.com> wrote:

This is precisely what I was trying to describe :
http://glinden.blogspot.com/2008/01/optimizing-web-20-applications.html

Again, if you do it transparently, that means that the stub which loads the missing code must do it synchronously.  On current browsers, that means the browser chrome is totally locked up while waiting for the new code, and the code already in the browser can't be doing anything useful.  The solution to that requires that the code be aware that it is making a "cross module" call, and to be prepared for it to take a while (and drop back into the event loop) if it hasn't already been loaded, so the only solution that makes sense to me is an asynchronous call much like the GWT RPC interface.

evaleto genebio

unread,
Mar 5, 2008, 7:43:43 AM3/5/08
to Google-Web-Tool...@googlegroups.com
Hi,
> I would be interested in the code...
I'm dealing something with my work team and my boss about gpl
licencing. We have to wait some days before it will published.

> are you adding applications dynamically or are they all references from the HTML statically ?

Currently it's statically. But it's dynamic on the point of view of
OSGI plugins (eclipse equinox). You can develop modules on separate
osgi plugins , and at runtime, the main plugin will publish the
available gwt modules. In this way you have a dynamic modules
integration.

The second use case will the availability to access on each modules
from javascript. There is Registry interface to query/create/event the
available modules. This part is not completly implemented but it is
quite easy to do it.

Thanks,
Olivier

Sanjiv Jivan

unread,
Mar 5, 2008, 8:54:46 AM3/5/08
to Google Web Toolkit Contributors
John,
Completely agree that loading has to be asynchronous, like the GWT-RPC
mechanism.

It would be nice if the GWT.createAsync mechanism for "lazy loaded"
portions of the app does its own dirty checking a small code change in
one of the lazy loaded portions doesn't cause the JS for the main app
to be reloaded. I also like Evaleto's concept of OSGi in the context
of GWT. Just thinking out loud.. consider a tree menu or tab menu
which is OSGi aware, and the deployment of files on the server cause
the new item to appear or be removed. I can see this being quite
valuable in a SaaS environment which is typically RIA and GWT would be
well suited for such apps.

Sanjiv

On Mar 4, 6:58 pm, "John Tamplin" <j...@google.com> wrote:

Joel Webber

unread,
Mar 6, 2008, 9:58:51 AM3/6/08
to Google-Web-Tool...@googlegroups.com
The IFrames are a very bad choice:
- Memory leaks (I posted a bug about this, including a fix, but nobody
seems to care about it)

My apologies if we missed a memory-leak case. Can you post a link to this issue? I didn't see it with a quick search.

Thanks,
joel.

stuckagain

unread,
Mar 10, 2008, 9:34:53 AM3/10/08
to Google Web Toolkit Contributors
Hi Joel,

Here is the bugid:
http://code.google.com/p/google-web-toolkit/issues/detail?id=1821

It was marked as NotPlanned because you could not reproduce the
problem. The problem is that you were running code that I created to
show a possible solution to the memory leak.

I just don't have the time nor the connectivity options (no direct
internet connection from my development machine) here at work to
create a patch and post it.

David
Reply all
Reply to author
Forward
0 new messages