views:

2406

answers:

5
+1  Q: 

gwt lazy loading

Is it possible in a large GWT project, load some portion of JavaScript lazy, on the fly? Like overlays.

PS: Iframes is not a solution.

A: 

I think this is what you are looking for.

<body onload="onloadHandler();">
<script type="text/javascript">
function onloadHandler() {
 if (document.createElement && document.getElementsByTagName) {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = './test.js';
  var heads = document.getElementsByTagName('head');
  if (heads && heads[0]) {
   heads[0].appendChild(script);
  }
 }
}
function iAmReady(theName) {
   if ('undefined' != typeof window[theName]) {
       window[theName]();
   }
}
function test() {
   // stuff to do when test.js loads
}        
</script>

-- test.js

iAmReady('test');

Tested and working in Firefox 2, Safari 3.1.2 for Windows, IE 6 and Opera 9.52. I assume up-level versions of those should work as well.

Note that the loading is asynchronous. If you attempt to use a function or variable in the loaded file immediately after calling appendChild() it will most likely fail, that is why I have included a call-back in the loaded script file that forces an initialization function to run when the script is done loading.

You could also just call an internal function at the bottom of the loaded script to do something once it has loaded.

Grant Wagner
+1  A: 

GWT doesn't readily support this since all Java code that is (or rather may be) required for the module that you load is compiled into a single JavaScript file. This single JavaScript file can be large but for non-trivial modules it is smaller than the equivalent hand written JavaScript.

Do you have a scenario where the single generated JavaScript file is too large?

A: 

You could conceivably split your application up into multiple GWT modules but you need to remember that this will limit your ability to share code between modules. So if one module has classes that reference the same class that another module references, the code for the common class will get included twice.

Effectively the modules create their own namespace, similar what you get in Java if you load the same class via two separate class loaders. In fact because the GWT compiler only compiles in the methods that are referenced in your code (i.e it does dead code elimination), it is conceivable that one module will include a different subset of methods from the common class to the other module.

So you have to weigh up whether loading it all as one monolithic module and taking an upfront hit the first time round is better than having multiple modules whose cumulative code size might well be significantly greater than the single module approach.

Given that GWT is designed so that the user should only ever load the same version of a module once (it is cached thereafter), in most cases the one off upfront hit is preferable.

Simon Collins
A: 

Hi,

Try to load a big GWT application with the "one upfront" approach using a iPhone or an iPod touch...it will never load.

The module approach is a but more complexe to manage but better for smaller client devices.

Now, how do I load a module from my Java code without using an iFrame?

  • Erick
+2  A: 

Check out GWT.runAsync as well as the Google I/O talk below, which goes into lazy loading of JavaScript in GWT projects.

Eric W.