Hello.
This is certainly a nice feature, but one not requiring a monolithic
compile would be that just great.
Our application is built on top of OSGi. When a new module is added a new
menu item appears in the GUI to access that module GUI (under different
URL).
Currently we must compile each OSGi module with the common "Workspace"
library project and so the common Workspace part is duplicated over the
modules and so needs to be loaded together with each module code. This is
because of the monolithic build.
Much nicer would be a separate Workspace module that just lazy-loads its
(OSGi based) dynamic view modules on demand (menu item clicks). Is there
any plan to make possible to do it like this?
Thanks in advance.
For more information:
http://code.google.com/p/google-web-toolkit/wiki/CodeSplitting
Hello.
This is certainly a nice feature, but one not requiring a monolithic
compile would be that just great.
Our application is built on top of OSGi. When a new module is added a new
menu item appears in the GUI to access that module GUI (under different
URL).
Currently we must compile each OSGi module with the common "Workspace"
library project and so the common Workspace part is duplicated over the
modules and so needs to be loaded together with each module code. This is
because of the monolithic build.
Much nicer would be a separate Workspace module that just lazy-loads its
(OSGi based) dynamic view modules on demand (menu item clicks). This way
there would be no page reload (= the same URL), because the Workspace
(header, menu, footer, common code) doesn't need to be reloaded. Is there
any plan to make possible to do it like this? I think I ask for the same
as mirceade does.
@m.zdila: Right now, so many of GWT's biggest speed benefits are a direct
result of monolithic compilation of modules, so adding features to
encourage runtime modularity is not something we're really considering
anytime soon. While we understand the desire to not include shared code
redundantly, the optimal solution would have only one module at runtime in
the first place. Is there no way you can compile together the necessary
OSGi modules together ahead of time, so that they can benefit from compiler
optimizations?
@br: We can compile together the client code for all the current modules,
but it would not be very OSGi conforming. For example, imagine that some
client bought our product including only some of the modules. It would not
be very clean to include client code for all the existing modules as one
monolithic build. Even if we gave him only the client code for the bundles
he bought, then if he would buy additional bundle(s) and dynamically
install it to the running system, there would be no chance to add the
additional client side part to the existing monolithic build. Simply, each
server-side user bundle should have its client module counterpart so they
can be dynamically added/removed without recompiling (all) the client.
Currently, as described in my first post, the shared workspace code gets
duplicated. And exactly this is what makes traversing between modules slow
- the JS code must be dowloaded every time (if not cached), parsed, and the
workspace initialization code must be run. This way the monolithic build
give us the opposite of the desired speed improvement.
I admin that I don't know much about the optimization internals. Despite of
that I dare to imagine that (in a near future) it would be possible the
common workspace module to be separated from the view modules. The
optimization can stay within the single module (build). The interface
between workspace and view is governed by the Java interfaces (or maybe
even the classes) and so the compiler can take it to the accound when
optimizing. I personally would rather have this functionality even if the
code would not be as much optimal as possible ;-).
In any case, currently we can live just OK with our current solution. Good
luck!
The problem is, if you support separate compilation, the compiler can no
longer make assumptions about which methods in your code base are 'live'
(are going to be called) and which are 'dead' (are never called), it would
be forced to include them on the chance that they might be called in the
future by some third party module. This would massively bloat the size of
the JS output as well as hamper other optimizations like inlining which
depend on knowing things like that if an interface I is implemented by
classes A and B, and B is never used, than I == A. This comes up frequently
with say, List/ArrayList/LinkedList where LinkedList is rarely if ever used.
In my opinion, what you really want is some kind of message bus or RPC
mechanism, so that differently compiled packages can communicate over some
interface. In this case, the amount of shared code that must be replicated
can be kept to a minimum.
cromwellian: I don't understand how could the RPC solve my problem.
Maybe what I would like to have is currently very complicated in the GWT. I
am accepting it and can live with that.
Long time ago I was using DOJO and I was dynamically loading the views to
the workspace. I know it has nothing to do with the GWT, I only want to
tell you that some other frameworks can do it. (Un)fortunately I wouldn't
use any JS-only framework even if it had such an feature :-).
Anyway it would be great if GWT had some means to do the true dynamic code
loading. It doesn't have to be necessairly transparent for the developer. I
wouldn't mind to somehow explicitly mark some code "interface points" or
something...
We are also searching for solution to dynamically extend the GUI produced
via GWT.
Regarding Cromwellian's comment about the compiler optimizations and the
static analysis of what code parts are "live" or "dead", I would say that
what we want is something like JARs for GWT. Have the base GWT application
compiled as one or more JAR-like packages, develop you extensions/plugins
against the main application's API and package them as JAR-like files. At
runtime of course you as the application owner must make sure that all
required JARs/bundles are present. But hey, that's exactly what people know
from JAVA apps. If you miss a JAR file you will get a
ClassNotFoundException.
Just a message to the Google GWT team that while I appreciate the
theoretical utility of pruning unused methods, especially as applicable to
the GWT core UI classes themselves, the applicability to end-user code is
likely much less.
I routinely run dead code analysis against my source and remove unused
methods. So, while it's nice that the compiler would do that for me, it is
certainly not a necessity. If a developer's code is too big because of
dead code, it should be on his/her shoulders to fix it themselves.
If somehow we (end-users) could control which modules were pruned of
un-invoked methods it may serve to solve part of the problem. A user such
as m.zdila who would like their user's "plugins" to have full access to the
UI component APIs could turn off (all?) pruning. Sure, maybe the result
would be a 2meg JavaScript file, but that's his choice.
I'm not a GWT team member, but I'll comment. It's not just pruning unused
methods. It also affects obfuscation and a number of other things that
make 'separate compilation/linkage' a difficult prospect.
In order for N different separately compiled programs to be linked at
runtime, they'd all have to agree upfront on what the names of every
publicly available class, method, and field were in the output ahead of
time. This would have the effect of lengthening the names of most of the
identifiers, further ballooning code.
Then there's inlining and type-tightening. Currently, the compiler is able
to detect when a method is not polymorphic (no overrides), and turn it into
a static method. Moreover, in many cases, it can inline this method.
Compile time linkage would prevent this, and the compiler would be forced
to conclude that any non-final method can potentially be overriden,
disabling inlining and prototype-chain reduction effects.
There are lots of other problems to. You're essentially asking GWT to run
in "Java to Javascript translator mode" rather than "Java to Javascript
compilation" mode, akin to the way hand coded Javascript apps are
architected.
@brett: What Ray said. Also, we don't want to create the web equivalent of
DLL Hell, which is a very easy situation to get into. Finally, and most
importantly, runtime modularity simply has a really high performance cost
because HTTP round-trips over the internet are inevitably slow and so we
strive to encourage architectures that avoid them. All that said, I think
there are a few things we'll do before long (e.g. making it easy to expose
JS-callable APIs from GWT modules, like Ray's gwt-exporter) could go a long
way toward providing some amount of dynamic pluggability without sacrficing
too much in the way of performance.