JavaScript and Screen Responsiveness

Posted on 2010-06-01 23:38 in Blog • Tagged with javascript, programming

Lately, I’ve been playing around with JavaScript, creating a visualizer for my next AI game competition (in the fall?). I’ve decided to deviate from my past setup; instead of displaying live games on the over head, I will instead be recording player action to a log file and then replaying the results on the overhead. This log file can then be provided to the participant, allowing them a detailed look at all the steps their AI took during a sample game.

The problem I discovered involved the rate at which changes are painted to the screen.

$(".note").html("Message one");
sleep(5000); // example 5 second sleep routine  
$(".note").html("Message two");  

With the above code snippet, one would expect Message one to appear, be displayed for five seconds, and then get replaced with Message two. Instead, something surprising happens. When the script is run, no message appears, the page freezes for five seconds, and then the second message appears. The first message is never displayed.

The cause for this is quite surprising. It appears most browsers (the three I tested) wait until the JavaScript function has completed running before it starts updating the displayed page. I believe this was the case initially because the JavaScript interpreter and the page rendered ran in the same thread, so the two tasks could not be accomplished concurrently. Today, this behavior is probably maintained the same for backwards compatibility. I cannot fathom why this behavior would be written into a JavaScript specification, so that is probably not the culprit.

The fix appears simple, but can get quite complicated. JavaScript provides a time routine, that runs a function of your choosing during each timer tick. (JavaScript does allow for multiple timers to run in parallel)

var id = setInterval ( "desiredAction()",1000 );  
function desiredAction ( ){  
    // action code  
    if(lastAction){  
        clearInterval( id );  
    }
}

This is great if you want to perform the same operation for each tick, but in my case, sometimes I wanted to update text, other times move images. To solve this problem, as I parsed the log file, I queued up all the different events in an array. During the timer tick, I removed the first item in the queue and called the associated function pointer to perform the desired specific action.

function performEventQueueAction(){  
    // verify there are actions left  
    if(window.game.eventQueue.length > 0){  
        var action = window.game.eventQueue.shift(); // remove item in front of array  
        action.func( action.data ); // use function pointer with saved data  
    }  
    // stop rendering when actions complete  
    else{  
        clearInterval( window.game.eventInterval ); // stop timer  
    }  
}  

With this tasking, the page stays responsive because the event handler is available to respond to mouse clicks for browsing to the different portions of the page, and all the game display events occur in the order desired, in the approximate time desired.


Continue reading

XmlHttpRequest

Posted on 2010-03-31 23:10 in Blog • Tagged with javascript, programming

I was reading about Websockets and their usefulness the other day when I realized how little of their precursor, the XmlHttpRequest, I actually knew. I performed some research and code a few quick and dirty example pages and discovered a new realm of capabilities that I was previously ignorant about.

For years, I had assumed AJAX technology was only useful if there were server side scripts interpreting the requests, gathering the needed data, and returning well formatted responses. These responses were then used to update the page content.  While coding one of the examples, I had an ‘Ah-ah moment’.  AJAX capabilities could be utilized to load static content when updating the page.  Instead of having to address PHP or ASP pages, plain old HTML files could be the target.

Within minutes, I had seamlessly written a basic homepage, consisting of several sections that loaded all the content without a single page refresh. This game me a liberating feeling. Now I can update the content without losing my JavaScript variable values.

Quick Example

The simplest way to dynamically load content is to specify

/* Create the request object */  
if (window.XMLHttpRequest) {        // Modern browsers  
    xhttp = new XMLHttpRequest();  
} else {                            // Old Internet Explorer  
    xhttp = new ActiveXObject("Microsoft.XMLHTTP");  
}
/* Perform the request */  
xhttp.open("GET","external\_file.txt",false);  
xhttp.send("");  
destinationElement.innerHTML = xhttp.responseText;

This creates a new XmlHttpRequest object across multiple browser types.  The ‘open’ command defines how the file will be retrieved (GET vs. POST) and the URL for the file.  Send performs the actual communication with the server.  After the communication is complete, responseText is extracted and displayed to the user.

This block of code is very straightforward and very misleading.  It performs no error handling (file not found) and does not take into account the amount of time needed to retrieve file (server load).

Better Example

A better approach would be to use a JavaScript library that is designed for this type work, JQuery.

$(".destinationElement").load("external_file.txt");

This single line of JavaScript performs the same function as the block of code above. It says load the contents of the files, external_file.txt, into the DOM element whose title is ‘destinationElement’.

Again, this over looks the same errors the first block contained, errors while loading the file and what not.  Luckily, JQuery has built in error handling events. As a programmer, we can define what action should be taken when a query fails.

$(window).error(function(msg, url, line){  
    // handle the error  
});  

Quick note: The above block will catch all errors that occur, not just errors AJAX errors.


Continue reading