gwt延迟加载
在大型GWT项目中,是否有可能在运行时动态加载JavaScript的某些部分?
像叠加层。
PS:iframe不是解决方案。
解决方案
回答
我认为这就是我们要寻找的。
<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');
经过测试并在Firefox 2,适用于Windows的Safari 3.1.2,IE 6和Opera 9.52上运行。我认为这些版本的上层版本也应该工作。
请注意,加载是异步的。如果我们在调用appendChild()
之后立即尝试在加载的文件中使用函数或者变量,则它很可能会失败,这就是为什么我在加载的脚本文件中包含了一个回调,该回调会强制初始化函数在脚本加载完成。
我们也可以只在加载的脚本底部调用内部函数,以在加载脚本后执行某些操作。
回答
GWT并不容易支持这一点,因为我们加载的模块所需的(或者可能需要的)所有Java代码都被编译到一个JavaScript文件中。该单个JavaScript文件可能很大,但对于非平凡的模块,它比等效的手写JavaScript小。
我们是否有单个生成的JavaScript文件太大的情况?
回答
我们可以想象将应用程序拆分为多个GWT模块,但是我们需要记住,这将限制我们在模块之间共享代码的能力。因此,如果一个模块具有引用另一个模块所引用的同一类的类,则该通用类的代码将被包含两次。
实际上,这些模块创建了自己的名称空间,类似于通过两个单独的类加载器加载同一类时在Java中获得的名称空间。实际上,因为GWT编译器仅编译代码中引用的方法(即,它消除了死代码),所以可以想象一个模块将包含从公共类到另一模块的不同方法子集。
因此,我们必须权衡一下是否全部将其作为一个整体模块进行加载并在第一轮中取得先发优势,要比拥有多个模块的累积代码大小可能明显大于单个模块方法要好。
鉴于GWT的设计目的是使用户只能加载一次相同版本的模块(此后将其缓存),因此在大多数情况下,最好选择一个非常规的版本。
回答
尝试使用iPhone或者iPod touch的"前期"方法加载大型GWT应用程序...它将永远不会加载。
模块方法管理起来比较复杂,但是对于较小的客户端设备则更好。
现在,如何在不使用iFrame的情况下从Java代码加载模块?
- 埃里克
回答
查看GWT.runAsync
以及下面的Google I / O演讲,该演讲将懒惰地加载到GWT
项目中的JavaScript中。
- http://code.google.com/p/google-web-toolkit/wiki/CodeSplitting
- http://code.google.com/events/io/sessions/GoogleWavePoweredByGWT.html(大约25:30)