GWT:在页面准备好之前开始运行(或者正文资源不会阻止运行 gwt)?
Posted
技术标签:
【中文标题】GWT:在页面准备好之前开始运行(或者正文资源不会阻止运行 gwt)?【英文标题】:GWT: Start running before page is ready (or body resources do not block running gwt)? 【发布时间】:2012-05-21 19:53:52 【问题描述】:在我的 html 页面中有外部图像和 Flash,有时它们加载缓慢。我的 gwt 应用程序总是在加载后开始运行。我使用 xsiframe 链接器。
在加载正文中的任何图像和资源之前,有什么方法可以开始运行 gwt?或者确保加载其他内容不会阻止启动 gwt。
编辑:我创建了一个重现问题的最小项目:
入口点:
public class MyEntryPoint implements EntryPoint
public void onModuleLoad()
Window.confirm("onModuleLoad");
html页面:
<html><head>
<script type="text/javascript"src="nocache.js"></script>
</head><body>
<!-- http://***.com/questions/100841/artificially-create-a-connection-timeout-error -->
<img src="http://10.255.255.1/timeout.gif" />
</body></html>
【问题讨论】:
这里developers.google.com/web-toolkit/doc/latest/…解释了加载顺序和哪些元素阻塞了GWT的执行。这可能会对你有所帮助。 @jaxb 谢谢,我已经读过了。遗憾的是它没有回答我的具体问题(困惑)。 您是否尝试将 *.nocache.js 放在正文的第一个脚本标记中? @GaneshKumar 是的,我已经尝试过了。 nocache.js 总是启动并加载特定于浏览器的脚本,但在加载图像之前调用 onModuleLoad 会被阻止。 根据 GWT 文档,onModuleLoad() 调用不需要等到图像加载完成。你能发布你的html页面吗? 【参考方案1】:我能想到两种可能的解决方案:
1。 xs 链接器
您可以使用旧的“xs”链接器代替“xsiframe”。这不是很好,特别是因为 xs 在开发模式下不起作用。但也许您可以在开发过程中使用 xsiframe,然后切换到 xs 进行真正的构建、测试和生产。
2。 <noscript>
标签技巧
您可以将页面内容,尤其是加载缓慢的图片,放入<noscript>
标签中,如果浏览器不支持JavaScript,则使用该标签。
如果启用了 JavaScript,则在加载过程中会忽略该标记的内容。所以我们将在我们的 GWT 代码(可以再次使用 xsiframe 链接器)中将 noscript 标记的内容复制回真实页面。
这里有一些快速代码:
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" language="javascript"
src="http://cdn.example.org/.../some.nocache.js"></script>
</head>
<body>
<noscript>
<p>A</p>
<img src="http://10.255.255.1/timeout.gif" />
<p>B</p>
</noscript>
<p>Test (should appear immediately if JavaScript is enabled)</p>
</body>
</html>
@Override
public void onModuleLoad()
final NodeList<Element> noscriptElems =
RootPanel.get().getElement().getElementsByTagName("noscript");
final Element noscriptElem = noscriptElems.getItem(0);
RootPanel.get().add(new Label("Here is GWT"));
RootPanel.get().add(new HTMLPanel(noscriptElem.getInnerText()));
/* Be careful of course, not to have bad html in your noscript elem */
【讨论】:
【参考方案2】:首先,很抱歉在我对 GWT 不太了解时“回答”,并提出了一个非常丑陋的 hack。
那么,两个具有未定义结果的异步加载对我来说听起来像是一种竞争条件。所以我想说你需要“锁定”你的图像/闪存,直到应用加载并“解锁”它们。
执行此操作的一种方法可能是给所有资产一个虚拟属性而不是src
,然后让应用程序将虚拟属性复制到真实的src
。它看起来像这样:
HTML 示例:
<img data-src="site.com/image.jpg" />
入口点:
public class MyEntryPoint implements EntryPoint
public void onModuleLoad()
var images = document.getElementsByTagName('img');
for(var i=0; i<images.length; ++i)
var dataSrc = images[i].getAttribute('data-src');
if(dataSrc) images[i].src = dataSrc;
// ... rest of your entry point code
也许你可以调整这样的东西来满足你的需要。
【讨论】:
谢谢,问题不在于连接,我已经在 cmets 中描述过了。我还描述了为什么您的解决方法对我不起作用,即使没有 ajax/js/gwt,我也需要一个可查看的网站。如果我有这个选项,我会异步加载页面内容。事实上,我正试图找出 gwt 的问题所在。 对不起。你是对的,我忽略了页面在没有应用程序的情况下可见的要求。不过,我仍然说您有竞争条件,您需要“锁定”图像。您可以在页面本身中使用内联脚本在超时后解锁图像吗?这样你就不用依赖应用了,但它仍然使用 JS。 我已将alert('hello');
添加到 gwt 文件的末尾。它在没有被图像加载锁定的情况下执行,因此问题不是竞争条件,并且 gwt 文件已正确加载和执行。问题可能在于 gwt 用于启动应用程序的事件(调用 onModuleLoad
)。【参考方案3】:
由于您只对本地资源有问题(呃!),我想using a <base>
as a plug would be a great idea:
<head>
<base id="src-plug" href="http://src-plug/"/>
<script>
function unplug()
setTimeout(function()//or whatever; I guess ondomready
var srcPlug = document.getElementById('src-plug');
srcPlug.parentNode.removeChild(srcPlug);
,5000);
</script>
</head>
但是显然在移除了基础之后,资源仍然需要重新加载一些类似的东西
$('img').each(function()
$(this).attr('src',$(this).attr('src'));
);
大约在这一点之后,我意识到这一点或任何客户端解决方法都不是一个好主意
相反,您为什么不通过不同的子域(类似于 CDN)提供内容?为静态资源设置带有自定义缓存策略等的无 cookie 域通常是个好主意。
【讨论】:
我已经在使用不同的域作为 cdn,这就是我使用 xsiframe 链接器的原因。【参考方案4】:我知道这是一个非常古老的问题,但在搜索此问题时,它仍然是谷歌的热门话题。
现在另一种解决方案就是将 loading="lazy" 添加到图像中。 (不确定这是否适用于闪存)。
【讨论】:
以上是关于GWT:在页面准备好之前开始运行(或者正文资源不会阻止运行 gwt)?的主要内容,如果未能解决你的问题,请参考以下文章
在Mac OSX 上配置Appium+Android自动化测试环境