Chrome's loading indicator keeps spinning during XMLHttpRequest

Martin Konecny picture Martin Konecny · Apr 24, 2010 · Viewed 25.1k times · Source

I'm writing an AJAX web app that uses Comet/Long Polling to keep the web page up to date, and I noticed in Chrome, it treats the page as if it's always loading (icon for the tab keeps spinning).

I thought this was normal for Google Chrome + Ajax because even Google Wave had this behaviour.

Well today I noticed that Google Wave no longer keeps the loading icon spinning, anyone know how they fixed this?

Here's my ajax call code

var xmlHttpReq = false;
// Mozilla/Safari
if (window.XMLHttpRequest) {
   xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
   xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpReq.open('GET', myURL, true);
xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttpReq.onreadystatechange = function() {
   if (xmlHttpReq.readyState == 4) {
      updatePage(xmlHttpReq.responseText);
   }
}
xmlHttpReq.send(null);

Answer

Marcel Korpel picture Marcel Korpel · Apr 26, 2010

I shamelessly stole Oleg's test case and adjusted it a bit to simulate long-polling.

load.html:

<!DOCTYPE html>
<head>
  <title>Demonstration of the jQery.load problem</title>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script>
  jQuery(document).ready(function() {
    $('#main').load("test.php");
  });
  </script>
</head>
<body>
  <div id='main'></div>
</body>
</html>

test.php:

<?php
  sleep(5);
?>
<b>OK!</b>

The result is interesting: in Firefox and Opera, no loading indicator is shown during XMLHTTPRequests. Chrome lets it spinning... I suspect Google Wave doesn't use long polling anymore (but, for instance, polls every X seconds, to save resources), but I can't test it, as I don't have an account.

EDIT: And I figured it out: after adding a little delay in loading test.php, which can be as small as possible, the loading indicator stops after load.html has been loaded:

jQuery(document).ready(function() {
  setTimeout(function () {
    $('#main').load("test.php");
  }, 0);
});

Somehow, as is confirmed in a comment on another answer, when the browser gets control back to finish page rendering, the indicator stops spinning. Another advantage is that the request cannot be aborted by pressing Esc.