In my html page there are external images and flashes, sometime they load slowly. My gwt app always starts running after they are loaded. I use xsiframe linker.
Is there any way to start running gwt before loading any images and resources which are inside body? Or make sure loading other things will not block starting gwt.
EDIT: I have created a minimal project that reproduces the problem:
entry point:
public class MyEntryPoint implements EntryPoint {
public void onModuleLoad() {
Window.confirm("onModuleLoad");
}
}
html page:
<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>
There are two possible solutions I can think of:
You could use the old "xs" linker instead of "xsiframe". This is not so nice, especially because xs doesn't work in dev mode. But maybe you could use xsiframe during development, and then switch to xs for the real builds, tests and production.
<noscript>
tag trickYou can put the page contents, especially the slowly loading images, into a <noscript>
tag, which is used, if the browser doesn't support JavaScript.
If however JavaScript is enabled, then the contents of that tag are ignored during loading. So what we will do in our GWT code (which can use the xsiframe linker again), is to copy the contents of the noscript tag back into the real page.
Here's some quick code:
<!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 */
}
First, sorry for "answering" when I don't know too much about GWT, and for presenting a pretty ugly hack.
Now then, two asynchronous loads with undefined outcome sounds like a race condition to me. So I'd say you need to "lock" your images/flash until the app loads and "unlocks" them.
One way to do this might be to give all the assets a dummy attribute instead of src
, and then to have the app copy the dummy over to the real src
. It would look something like this:
HTML example:
<img data-src="site.com/image.jpg" alt="loading..." />
Entry point:
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
}
}
Maybe you can adapt something like this to fit your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With