5

在我的 html 页面中有外部图像和闪光灯,有时它们加载缓慢。我的 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>
4

4 回答 4

2

我能想到两种可能的解决方案:

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" 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 */

}
于 2012-05-24T09:55:01.700 回答
1

首先,很抱歉当我对 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
    }
}

也许你可以调整这样的东西来满足你的需要。

于 2012-05-22T06:10:52.557 回答
1

由于您只遇到本地资源问题(呃!),我认为使用 a<base>作为插件将是一个好主意

<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 域通常是个好主意。

于 2012-05-23T09:55:35.810 回答
0

我知道这是一个非常古老的问题,但在搜索此问题时,它仍然是谷歌的热门话题。

现在另一种解决方案就是将 loading="lazy" 添加到图像中。(不确定这是否适用于闪存)。

于 2020-09-12T16:58:09.487 回答