0

I have a JavaScript that loops through a xml to display content. It take about 3-5 seconds to complete. In the mean time, I would like to incorporate a loading gif, however, the gif is load animating until after the JavaScript is complete. By that time, I want to to disappear. (For testing purposes, I did not have it disappear to ensure the gif was in fact working. Below I have what works to display and hide the gif content, so that I don't need help with.

I think my idea is related to How to show loading gif image while content called via javascript is loading? however different that it does not use buttons to call JavaScript, it's called when the page is loading.

In .html

<div id="loading"><img src="loading.gif"/>Starting Content</div>

In .js

function Loaded(quantity) {
  $(document).ready(function() {
        $("#loading").html("New Content");
  });
}

As I said, the idea works to show/hide the gif, just the gif fails to animate which defeats the purpose of having it. :)

Community
  • 1
  • 1
Jeremy
  • 767
  • 1
  • 5
  • 7
  • So just to clarify, this 3-5 seconds of time is spent in a tight loop, and it's not asynchronous? – Matti Virkkunen Dec 31 '12 at 14:50
  • Why are you declaring `$(document).ready` within a `Loaded` function? It already binds to `DOMContentLoaded`. Are you sure that your xml parsing is being done asynchronously as @MattiVirkkunen suggests it *should* be done? – Joseph Yaduvanshi Dec 31 '12 at 15:45
  • Jim: I'm calling Loaded after the XML JavaScript has finished, so it can overwrite the div text. Matti & Jim: It's not asyuncronous. I'm working on apsillers method to incorporate the setTimeout, but having a little trouble with it since the function has several variables pulled from outside of the function within the doSomethingHeavy part. – Jeremy Dec 31 '12 at 18:24
  • @JimSchubert Thanks for your thoughts. I've been able to incorporate into the document.ready function to count up the results as they load as opposed to having a loading bar. I'm not certain if you're meaning there is another method of what I'm doing using `DOMContentLoaded` so I wouldn't know how to change it over at this time, if it were more efficient. All is giving desired results now. – Jeremy Dec 31 '12 at 19:07

2 Answers2

3

Long-running JavaScript jobs block the browser's UI, including image animations. To see this in action:

  1. Go to http://www.ajaxload.info/ and click "Generate it!" to make a GIF spinner.

  2. Run i=0; while(i < 100000000) i++; in your browser console. The image will freeze while the loop completes.

In order to prevent this from happening, you'll need to make your loop have some kind of asynchronous component as described in Javascript - how to avoid blocking the browser while doing heavy work? (this question is very nearly a duplicate of that one, in fact):

for(var i=0; i < 1000000; ++i) {
    setTimeout(function(i) {
        return function() { doSomethingHeavy(i); }
    }(i), 0);
}

This queues up the steps of the loop, but it allows the JavaScript thread to "rest" between iterations of the loop, which in turns allows the UI thread to animate the GIF.

Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • +1 I've never thought to use ajaxload.info to demonstrate blocking in js. Excellent suggestion to visualize the problem, I'll have to use it in the future. – Joseph Yaduvanshi Dec 31 '12 at 15:47
  • @apsillers I actually tried `setTimeout` before, but not in the same fashion. Finally got yours referenced method to work. Since the title "blocking" and "heavy work" wasn't a familiar thought, I could not find it in the search. This made the loading of the XML appear faster (or at least, since its loading asynchronously), it doesn't need a loading gif. Thanks! :) – Jeremy Dec 31 '12 at 18:56
1

You should do heavy jobs in a web worker which allows heavy jobs to be done in another thread and not block the main thread. Besides, Chrome is properly support it.

Licson
  • 2,231
  • 18
  • 26