【问题标题】:GWT: Start running before page is ready (or body resources do not block running gwt)?GWT:在页面准备好之前开始运行(或者正文资源不会阻止运行 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://stackoverflow.com/questions/100841/artificially-create-a-connection-timeout-error -->
    <img src="http://10.255.255.1/timeout.gif" alt="timeout image" />
</body></html>

【问题讨论】:

  • 这里developers.google.com/web-toolkit/doc/latest/…解释了加载顺序和哪些元素阻塞了GWT的执行。这可能会对你有所帮助。
  • @jaxb 谢谢,我已经读过了。遗憾的是它没有回答我的具体问题(困惑)。
  • 您是否尝试将 *.nocache.js 放在正文的第一个脚本标记中?
  • @GaneshKumar 是的,我已经尝试过了。 nocache.js 总是启动并加载特定于浏览器的脚本,但在加载图像之前调用 onModuleLoad 会被阻止。
  • 根据 GWT 文档,onModuleLoad() 调用不需要等到图像加载完成。你能发布你的html页面吗?

标签: javascript gwt


【解决方案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" alt="timeout image" />
      <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" alt="loading..." />
    

    入口点:

    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" 添加到图像中。 (不确定这是否适用于闪存)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 2014-06-05
      • 1970-01-01
      相关资源
      最近更新 更多