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。 &lt;noscript&gt; 标签技巧

您可以将页面内容,尤其是加载缓慢的图片,放入&lt;noscript&gt;标签中,如果浏览器不支持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 &lt;base&gt; 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自动化测试环境

关于栈的析构问题

iframe 何时开始加载到页面上?

选择查询的准备语句问题

建立Azure Dev Ops持续集成和持续交付(CICD)(准备好Azure Web App资源)

建立Azure Dev Ops持续集成和持续交付(CICD)(准备好Azure Web App资源)