large apps code splitting idea (yes, again)

1 view
Skip to first unread message

sanny...@gmail.com

unread,
May 6, 2008, 6:09:51 AM5/6/08
to Google Web Toolkit Contributors

Hello, gwt developers. Would you please comment on the following:

Our app is big. If we do it as one large module - it takes too long to
load initially. If we split it by pages - page switch is slow. This
problem is known and was already discussed here and there.

I have a combined idea which seems to be new (at least, I did not see
it being discussed).

NB: Of course, I know the cons about compiling each model as a single
js, so here's other way.

IDEA:

Whole applications is compiled as a single large executable (IFRAME
MODE), but then comes linker. Linker scans application's gwt.xml,
where we have application layout specified for linker in the following
format:

<lazy-part name="part1">
<includes classes="my.package1.*"/>
<includes classes="my.package2.*"/>
</lazy-part>
<lazy-part name="part2">
<includes classes="my.package3.*"/>
</lazy-part>

When linker starts to work, the huge javascript code is already
produced, dead code eliminated, and all function names are unique. So
we can easily cut them according to these user-defined rules and put
into different files. Then, we load these files on demand.

This will require writing of custom parts loader, which has simple
API:

void doInLoadedPart(String partName, Runnable continuation)
void preloadPart(String partName, SomeCallback whenDone)
void addPartLoadingListener(PartLoadingListener listener)

In addition, we already used the following technique to pre-load gwt
modules (into non-gwt app):

SUB-IDEA (prefetching JS)

first, we load needed ABCDEF.cache.html in XmlHttpRequest in
background. We do it in idle time, while user does something on the
page; or we load it on demand when user clicks the button which
requires code which is not loaded yet.

second, when XmlHttpRequest returns "loaded", we add <script> tag to
current iframe, and script is loaded *quickly* (with a small delay
when JS is parsed). Again, i am talking only about iframe mode (not -
xs).

This approach does not disturb user by "opening ABCDE.cache.html"
status line and provides better overall user experience, because if
you use <script> tag with script that is not loaded yet, browser seems
to prevent JS execution at all and disables loading of images while
script is on its way (citation needed 8-)

SUB-IDEA (detecting idle time)

All images should have separate internal "onload" handlers (including
image bundles), so we can always track whether any image loading is in
progress; special API is provided. Most GWT apps I saw are text-based
ones (sorry for generalization) and this API could sound unnecessary,
but our program heavily uses graphics, so detecting idle time (when
images are all loaded) could be important for smooth user experience.

QUESTIONS:

I am currently thinking about implementing this (see main idea), but
did not look deep into GWT compiler yet. So, questions are

* do I muss something in (browser + gwt) architecture that could
prevent implementing this?
* in GWT 1.5 is linker API and also other APIs open enough to
implement this as a linker plugin? For example, I would like to add
"parts API" into selection script - can I do it in 1.5 now? Just read
SelectionScriptLinker::generateSelectionScript() - should I override
that and tweak large result string using indexOf()? (Sorry, no gwt
hacking experience yet)
* assuming no stoppers will emerge, and, as the whole idea seems to be
in the spirit of GWT, should I consider offering this as a
contribution to main GWT branch?

Waiting for your comments,
Alex.

P.S. this all assumes we're not limited by browser memory for storing
loaded JS, and app is written without memory leaks etc etc.

sanny...@gmail.com

unread,
May 6, 2008, 6:15:20 AM5/6/08
to Google Web Toolkit Contributors

quick add: parts dependency is needed (manual), too.

Joel Webber

unread,
May 7, 2008, 12:21:50 PM5/7/08
to Google-Web-Tool...@googlegroups.com
Alex,

Check out the following discussion. I believe the "GWT.createAsync()" idea addresses a lot of the issues you're running into, but in a (mostly) automated way:

We know this approach to be theoretically sound, and it shouldn't be too difficult to implement on top of the existing compiler.

Cheers,
joel.

sanny...@gmail.com

unread,
May 7, 2008, 1:58:57 PM5/7/08
to Google Web Toolkit Contributors
Joel,

Thanks for the link. The main answer is obtained: people already
thought about it and there's no stoppers for implementing it, and
linked article is good example.

Getting down to earth, people in that threads just chat about "it
would be good" and agreed on async loading API, everybody understands
it. But does anyone do something on this topic? Any plans?

Also, you mention "automated" way, but I could not see what was
automated in the discussion above. About code splitting boundaries: it
is very task-dependent and should be laid out by developer only, not
automatically. I saw no discussion on that layout.

Why I am asking it? Because I am going to implement it (Issue 620),
and I would like to see some constructive critical comments about, for
example, splitting code based on the package names as described above.
One positive idea which I found is: using .class instead of "part
name", that is much better reference to the "part", indeed.

Regards,
Alex.

Bruce Johnson

unread,
May 7, 2008, 2:15:11 PM5/7/08
to Google-Web-Tool...@googlegroups.com
Hi Alex,

GWT.createAsync() is something that we're definitely going to implement starting very soon, and it's a really well-vetted idea at this point. Sam Gross and Bob Vawter have both produced working proof of concept implementations. It will almost surely subsume any work you're going to do splitting things up by package, so I'd suggest that the best use of your time contributing in this area would be to help code review and tweak the GWT.createAsync() stuff rather than taking a different approach.

createAsync() has the features you're looking for:
- It's developer-directed in that you explicitly use GWT.createAsync() at points in your code at which you'd be willing to suffer a network delay. Even better, the compiler can compute the best strategies for how to arrange the chunks, potentially based on command-line flags that describe the running environment (or, better yet, totally automatically).
- It's a can't-go-wrong approach because the compiler computes the islands of reachability. Basically, as a developer you cannot create an arrangement that will fail; worst case, it would just not break up as optimally as you'd hope.
- It naturally integrates with deferred binding, so among other things it will allow code generators to generate code to take advantage of it without any developer intervention. A great example is RPC deserialization code; RPC can download per-type deserializers on demand.

Hope this puts you more at ease, and if you have additional use cases that you don't think are covered, please describe them.

-- Bruce

sanny...@gmail.com

unread,
May 7, 2008, 2:29:17 PM5/7/08
to Google Web Toolkit Contributors
Bruce, thank you very much; the approach you describe is definitely
better than mine! Compiler treats createAsync() calls as "weak"
references to hanging code regions, and does layout automatically,
based on createAsync() calls themselves.

Definitely, I would like to look at the code; at least to get into gwt
compiler; at most to use it ;-) Where should I look for it?

Cheers,
Alex

sanny...@gmail.com

unread,
May 7, 2008, 2:34:57 PM5/7/08
to Google Web Toolkit Contributors
>
> Hope this puts you more at ease, and if you have additional use cases that
> you don't think are covered, please describe them.

Only ideas that I listed above: notification callbacks and using
xmlhttprequest to load js into cache first.

Alex.

Bruce Johnson

unread,
May 7, 2008, 2:42:28 PM5/7/08
to Google-Web-Tool...@googlegroups.com
I think it's only on people's local filesystems at the moment, but we're making some more concrete plans around this now. Please stay tuned over the next few weeks as get the GWT 1.5 RC out and start building traction on the the follow up.
Reply all
Reply to author
Forward
0 new messages