Wednesday, September 21, 2011

Idle Ajax Polling

Web applications like to fetch new data resources in the background.  Javascript toolkits — in conjunction with Ajax browser technologies — allow the user interface to refresh application data asynchronously.  There is no need to reload the page.  jQuery has a suite of useful Ajax utilities for fetching new data and parsing it.  This frees up the user interface to notify the application server when it needs more data — perhaps on a recurring basis — each request polling for fresh information.  But should this sequence use a fire and forget approach?

Seeking new data
Web application user interfaces are different from their more traditional desktop counterparts.  With a desktop user interface, it's easy to listen for changes in data — changes the user is interested in.  For instance, one pattern might be to have your widgets act as observers on particular pieces of application data.  When the data changes, the widget is notified and can thus make the appropriate visual changes.

There is no need for desktop user interface libraries to poll for changes in the underlying application code — the application can notify the user interface.  However, with user interfaces that run inside a web browser, data is often stored on the remote application server — so it needs to stay informed.  This is easy enough for the user — they simply need to hit the refresh button and voila — up-to-date information.

The emergence of Ajax in Javascript user interfaces revealed some inefficiencies with the refresh button.  First of all, hitting refresh is going to retrieve a new copy of the entire web page — this is wasteful as we've already got the user interface — desktop applications aren't going to rebuild the entire screen when changes in data occur.  Second, you'll seldom find refresh buttons inside desktop user interfaces — the data finds the user.  In other words — web user interfaces should be automatically populated with changes in data.

Since it's difficult to have the application server notify the user interface about these changes — the Javascript needs to poll for data changes in the background.  When new data is detected, the interface is updated accordingly.  One potential issue with implementing a polling loop is how do we ensure minimal resource usage?  After all, each poll needs to travel through the network.

Idle windows
One approach to saving on resources with a polling Javascript user interface is to detect when the browser window is idle.  An idle browser window is one that is open with the user interface loaded, but not in focus on the user's desktop.  For example, the user might switch tabs or switch to another desktop window entirely.  We can attempt to capture these events and modify our polling logic fittingly.

Here is a simplified demo using jQuery that shows how we might use the focus and blur events to start and stop our polling loop respectively.

var poller;
$(document).ready(function(){
    function poll(){
        $('body').append($('<p></p>')
                 .html('Polled.'));
        poller = setTimeout(poll, 3000);
    }
    $(window).focus(function(event){
        $('body').append($('<p></p>')
                 .html('Active.  Starting poll...'));
        poll();
    });
    $(window).blur(function(event){
        $('body').append($('<p></p>')
                 .html('Idle.  Stopping poll...'));
        clearTimeout(poller);
    });
});

Resources saved
In the example above, we're polling (not actually polling anything, but you can see where the real Ajax code would go) every three seconds.  When the window becomes idle, we stop polling.  This signifies that the user is no longer interested in receiving new data from the application server.

By not polling for new data, we're not consuming network bandwidth.  We're also not consuming CPU cycles on the client when new data arrives.  This is a win for both the client and the web application.