Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome AJAX on page-load causes "busy cursor" to remain

In Google Chrome, AJAX called within $(function(){....}); seems to keep the page loading.

I have a site with a few pages with tabs. Because I'm using cheap godaddy hosting, I want the page to load as fast as possible. I thus want to load a page on 1 tab and then in the background use AJAX to load the other tabs. When I run AJAX from

$(function(){
    /*AJAX CODE HERE */
});

The cursor shows the page as loading for a long time (http://jsfiddle.net/mazlix/7fDYE/9/)

I have figured out a way (in chrome atleast) to somewhat fix that using setTimeout(); (http://jsfiddle.net/mazlix/7fDYE/8/), but this only works if you correctly predict when the window finishes fully loading and obviously makes it take longer to load. I want a way to load content via AJAX immediately after the page loads, so no "busy-cursor" is displayed while waiting for the returned AJAX.

like image 681
mazlix Avatar asked Jun 09 '11 03:06

mazlix


2 Answers

Google Chrome shows Loading Indicator as long as there are no new queries to servers. While the loading indicator is shown, all new requests are causing Chrome to extend the time the indicator is shown. Furthermore, when esc is pressed while the indicator is shown, all requests are aborted! These include AJAX requests and even Flash requests! Take a look at this question: i thought it was because of Youtube, but it turned to be Chrome's usual behavior.

The only way to avoid "extending" the time Loading indicator is shown, is making the requests after the loading indicator is hidden: i.e. when all queries to server are completed. JQuery's documentation on .load() says:

The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.

So, if you're sure that there are only images, scripts and frames on your page, window.load() will be fired just when you need it. Adding setTimeout() to it will work as you like. Here is an example: http://jsfiddle.net/7fDYE/22/

If there are other requests being made before your request, you should wait for them to be completed! For example, you know that besides the images/scripts etc. you have 3 more AJAX requests before the page loads. You can have something like this:

var loaded=0,needsToBeLoaded=4; //3 AJAX + window
function onLoad(){
    loaded++;
    if(loaded==needsToBeLoaded){
         //do the AJAX request   
    }
}
window.load(onLoad);
// add onLoad() to all 3 AJAX request handlers

I'm not sure what you can do with Flash requests...

like image 139
Hrant Khachatrian Avatar answered Nov 12 '22 18:11

Hrant Khachatrian


Update

This solution will not work for Chrome. It stops the loading indicator only when all requests made before window load have completed. The only solution appears to be to get it to make the request after window load, but as far as I know, this is only possible with setTimeout, which isn't great.


Update

To get around the pointer issue in Chrome, you could set the cursor style as shown in this fiddle. It's a bit hacky and it doesn't address the issue of the loading indicator at the top of the tab.


The loading indicator will be present in browsers until the page has loaded (window's load event). In $(function(){someCode();});, someCode is executed when the DOM load event is triggered (when all content has been parsed and inserted into the DOM, before page load). The execution of JavaScript at this point blocks the window's load event from firing, and so prevents the loading indicator from stopping. Note that image loading also blocks the window's load event.

Instead, you could try $(window).load(function(){someCode();});. In this example, someCode is executed when the window's load event is triggered. This is at the point where the browser's loading indicator stops.

So, instead of:

$(function(){
    /*AJAX CODE HERE */
});

Try:

$(window).load(function(){
    /*AJAX CODE HERE */
});

Note that this may cause your JavaScript to begin execution later, which may not be desirable.

like image 3
Spycho Avatar answered Nov 12 '22 19:11

Spycho