Using Asynchronous Javascript Programming in Internet Explorer


Each of the browsers have their own quirks and irritating ‘features’, and today we’re going to discuss one of Internet Explorer’s contributions. The issue is that IE delays rendering layout changes until the entire javascript thread has completed. In other words, if you have a javascript function that changes the text of an element three times, IE will wait until the entire function has completed, then render the final change (the last of the three changes).

IE does this for very good reasons. They can’t render the entire browser window every time a line of javascript is processed – the script would run incredibly slowly, and the screen would flicker like a mad thing. All the browsers have this issue. Each has come up with its own way to handle the problem; IE has come up with the rather simplistic solution of waiting until the entire thread has completed before it renders anything.

Most javascripts won’t notice this issue, and the script will run perfectly well, but there are two areas where I have encountered this problem quite often. The first is the use of a loading image while calling AJAX synchronously. There are two ways to us AJAX in a script: either you call the AJAX method, and tell it what to do when it returns, then forget about it and carry on processing (asynchronous) or you make the call and wait for the response to get back, then use that response in some way (synchronous).

If you use AJAX asynchronously, the return processing is done on a separate thread, so IE won’t delay the rendering until the return – it will simply wait until the original thread has completed, which is usually almost immediate. In our case, you would set the loading image, and then call the asynchronous AJAX method. That is the end of the thread, so the loading image is displayed immediately.

If you use AJAX synchronously, however, the return processing is done on the same thread, so the rendering is delayed until after the response has been processed. So, in our case, the loading image is only displayed after the AJAX call has finished (if at all – many times the loading image is intended to occupy an element while the AJAX call processes, then that element is populated with actual information). This isn’t really very useful at all.

The solution, of course, is to call the AJAX asynchronously, and set up a separate function to process the result. This is necessary, but very irritating. A synchronous process uses a single function, and all the variables are available in the correct scope. The Asynchronous response function runs in a completely different scope, so any variables you want to use there must be available in that scope as well.

The second issue is that of element measuring. I encounter this issue most often in animation, when it is important to know the exact dimensions of the elements we need to animate. We need to immediately be able to measure the effects of any text or image changes in order to compensate for them while animating. The problem is that the changes we make to the elements are not rendered immediately, so the changes they will have on the size of their containers doesn’t register.

So, for example, when adding a caption to a lightbox, we might want the caption box to slide up to its final position. In order to do that, we need to know how big it must be. The process would go like this:

  • Add the caption to the caption container
  • Measure the caption container
  • Animate the caption container

The problem, in IE, is that when it comes to the measuring part, the caption container reports its original size, even though it will report the new content. The new size will only be calculated once the entire thread has completed. This doesn’t help us very much at all.

The solution is to split the process into two parts, and to run the second part asynchronously. We call the second function asynchronously using the setTimout method, with a 0 timeout parameter:

setTimeout(‘secondMethodPath();’,0);

So the process now runs as:

First thread: Second thread:
  • Add the caption to the caption container
  • Call the second process asynchronously
  • Measure the caption container
  • Animate the caption container
  • The problems with this solution are the same as before – you are forced to break up the process into two separate methods, running independently, and the scope within which the two methods run is different, so you need to be very careful about which variables you use, and make sure they are available to both methods.

    Comments are closed.