Julian Jelfs’ Blog

Interrupted XmlHttpRequests cause IE to hang

Posted in Javascript by julianjelfs on May 6, 2009

I ran into a problem using MS Ajax script services recently. I was getting reports of intermittent hanging in IE (6 and 7) with some newly developed pages. I had a vague feeling it was something to do with the Script Services and a quick search revealed that this is a relatively well known problem.

As described in one of the responses to that question, the issues is caused when a page closes after an asynchronous ajax request is started but before it completes. In this scenario one of the browser’s available connections (of which it has 2 by default) is tied up and not released. So if this happens a couple of times, the browser has no available connections to service normal requests and appears to hang.

The solution is to abort any pending XmlHttpRequest when the page unloads. It’s not totally obvious how to do this when you are using Script Services with the generated proxy, because the actual XmlHttpRequest object itself is buried in multiple layers of magic. After a bit of digging I came up with the following solution:

$(function(){
    var pending = null;
    Sys.Net.WebRequestManager.add_invokingRequest(function(executor, args){
        pending = args.get_webRequest().get_executor();
    });

    Sys.Net.WebRequestManager.add_completedRequest(function(executor, args){
        pending = null;
    });

    $(window).unload(function(){
        if(pending!==null){
            pending.abort();
        }
    });
});

So what this does is just track the executor of the currently executing web request and set it to null when the request completes. On unload, we check if there are any pending request executors, and if there are we call abort on them. This prevents the hanging issue for me in IE which is a big relief.

Obviously this mechanism may not be adequate for you if ajax calls are not queued because there may be more than one pending request. In my case, all service calls are channelled through a queue so that can’t happen. Otherwise you would have to implement some mechanism to correlate the invoked request with the completed request.

Advertisements
Tagged with: ,

Javascript string concatenation performance

Posted in Javascript by julianjelfs on March 27, 2009

I was recently profiling some javascript code and began to suspect that the Microsoft Ajax.Net type extension String.format was causing some quite noticeable performance issue so I decided to run some tests to get to the bottom of it. The results were quite surprising.

Test 1 was normal string concatenation:

tf.AddTest(“StringConcat”, function(test){

test.Expects(1);

var start = new Date();

for(var j=0; j<10000; j++){

var str = “hello” + 1 + “hello” + 2 + “hello” + 3 + “hello” + 4 + “hello” + 5;

}

var end = new Date();

alert(end.getTime()-start.getTime());

test.Pass();

});

Test 2 was using the MS type extension:

tf.AddTest(“StringFormat”, function(test){

test.Expects(1);

var start = new Date();

for(var j=0; j<10000; j++){

var str = String.format(“hello{0}hello{1}hello{2}hello{3}hello{4}”, 1,2,3,4,5);

}

var end = new Date();

alert(end.getTime()-start.getTime());

test.Pass();

});

Test 3 was using a home made imitation of the MS type extension using regular expressions to fill in the blanks in the tokenised string:

tf.AddTest(“HomemadeFormat”, function(test){

test.Expects(1);

var start = new Date();

for(var j=0; j<10000; j++){

var str = format(“hello{0}hello{1}hello{2}hello{3}hello{4}”, 1,2,3,4,5);

}

var end = new Date();

alert(end.getTime()-start.getTime());

test.Pass();

});


where format is just a local function (which could easily be attached to the String prototype) defined as follows:

var format = function(tokenised) {

var args = arguments;

return tokenised.replace(/{[0-9]+}/g, function(matched) {

return args[parseInt(matched.replace(/[{}]/g, “”))+1];

});

}

Results for IE 7:
Test 1 : 328 milliseconds
Test 2 : 18626 milliseconds
Test 3 : 860 milliseconds

Results for Firefox 3.0.7:
Test 1 : 1 milliseconds
Test 2 : 6697 milliseconds
Test 3 : 431 milliseconds

Results for Google Chrome:
Test 1 : 8 milliseconds
Test 2 : 1958 milliseconds
Test 3 : 263 milliseconds

So, this is not particularly scientific and doing string concatenation in tight loops is not very realistic etc etc but a few things are pretty clear here. Firstly, simple string concatenation is by far the best approach. Secondly, IE performs a lot worse than the others with any approach. And thirdly, MS Ajax String.Format is a great deal worse than the homemade equivalent. Makes me wander what the other MS Ajax.Net script extensions are like …

Tagged with: ,