Appearance on EBA Ajax Podcast

The guys at EBusiness Apps – Andre Charland, Dave Johnson, Alexei White – have started a new weekly podcast on Ajax and invited me along for a general chat. They’re usually picking a general topic and riffing on it for a while – this week’s topic is long-term planning of Ajax projects … some companies aim to run their Ajax apps for up to 10 years, so what steps should they be taking to future-proof their apps, manage risks, and what future trends will there be? They invited me along.

It’s about an hour; the first few minutes are intro and a little discussion about the Ajax Design Patterns book.

As far as my own podcast, I should report here that I’ve actually been sitting on two new episodes, but didn’t release as the audio was quite poor on both. In the interests of proceeding with mor pattern podcasts, though, I will get them out soon, even if they have minimal shownotes for now. And getting the headset out again felt good, good enough to record some more.

Wanted: Massive Local Storage

Local storage – beyond 2KB cookies – is now a step closer with the latest Firefox effort. You get a local storage API like this:

javascript

  1. sessionStorage.setItem(..)
  2. globalStorage.namedItem(domain).setItem(..)

The fantastic thing is Brad Neuberg’s Dojo work means we can code independently of the local storage mechanism. Since IE also has local storage, as well as Flash, most bases are covered, or soon will be: Anyone with EITHER IE or Firefox or Flash will have local storage. (Incidentally, we had a discussion in the comments on Ajaxian about the possibility of S3 and other remote bindings as well, which I’m guessing Brad will implement at some point.)

But what I’d like to know, what I’d really really like to know, are the limits for these various techniques (I think Flash is 10MB per domain, right?)

As I’ve said before, there are valuable applications of massive storage – hundreds of gigs, e.g. media players that store data server-side, but cache content locally to cut down on the need for streaming from the server. Hopefully, these storage technologies won’t try to second-guess the imagination of web developers by setting a dumb arbitrary limit that “no-one would ever need more than”, like 100MB or 1GB or whatever.

If there’s room on my hard drive, and I trust the domain, let me store as much as I please.

Portable Comet? It’s the IFrame, Stupid!

Comet Takes to IE Like a Fish Takes to Acid

Comet – or HTTP Streaming, if you will – is a little sensitive when it comes to portability, and I’ll give you four guesses which major browser is causing the grief? Yeah, IE makes it difficult for two reasons: (a) IE’s XMLHttpRequest component doesn’t tell you anything about the response until the connection has closed – even if you try polling it instead of relying on onReadyStateChange, you’ll still get an empty string (Try it); (B) Okay, switch to plan B and inspect IFrame content – we can’t rely on onload, which is only called once at the end, so we must poll. But no, polling won’t help either, as the IFrame content remains empty until (you guessed it) the connection is closed. (Try it).

We’re Going Back, Way Back: Inline Script Tags

Don’t give up on the IFrame so fast … we’re closer than we think. Actually, the solution harkens back to one of the original Push techniques: outputting script tags with inline code (what the HTTP Streaming pattern calls “page streaming”). If you do that in your main document, the code will be executed immediately, and the same is true if you do that inside an IFrame.

I’m talking about a service that outputs stuff like this:

  1. <script type="text/javascript">
  2.     doSomething();
  3. </script>

So Make the Server Spit Out Inline Script Tags

The portable solution is this: Have the server continuously output script tags that call a known function in the parent frame. When you set the child IFrame’s source to point to this service, it will start evaluating the inline scripts as they pop out of the server. This happens to be one technique people have used for remoting for many years (I think Brent Ashley recently told me he was doing it in ?1999). The twist with Comet is that you keep doing it, and don’t actually close the connection for a while. (Again, I’m sure some people were doing that for a long time too!).

Is it elegant? No. It means the remote service is suddenly coupled to the client-side of the web app – it has to know something about what’s in the parent frame, whereas you’d often like it to be generic and just deliver a response in XML, JSON or whatever. Like most things Ajax, we’re using a hack because it nonetheless push all the right buttons for our users.

Try It. Portable Comet for the Masses

Here’s Some Code I Prepared Earlier

In the example above, the remote service outputs script tags in a loop – it’s a simple countdown service:

  1. <?
  2.   for ($i=$_GET&#91;"start"]; $i>=0; $i--) {
  3. ?>
  4.   <script type="text/javascript">
  5.     window.parent.onNewValue(<?= $i ?>);
  6.   </script>
  7. <?
  8.   }
  9. ?>

And in the browser’s initial Javascript, there’s a run-of-the-mill onNewValue() function, it looks something like this.

javascript

  1. function onNewValue(i) {
  2.   statusDiv.innerHTML = i; // Paint the new value onto the page
  3. }

See what I mean about coupling? The server-side service had to know that there’s a Javascript function defined in the parent called onNewValue(). At least we’ve minimised the coupling by using an Observer/Event style indirection approach – evidenced by the simple call to “onNewValue()”. It would be worse if it was the script that actually performed application logic directly, repainting the DOM with the new value.

IFrame is the new XMLHttpRequest

Whoever put the X in Ajax ought to put an I in Comit. IE’s XHR component doesn’t provide the response until the connection has closed, and I don’t think version 7 changes that. Assuming (graciously) it happens in IE8, you’ll need to use IFrame for the next five years if you’re doing any Comet work. And of course, you won’t need to do that, because libraries will do it for you.

BTW You could argue that IE is doing the right thing by preventing access to the content until the connection is closed. Maybe they are, maybe they aren’t. From a pragmatic perspective, though, portable Comet requires Ajax. Alternatively, use IFrame with IE and XmlHttpRequest with the others, though I’m not sure if there’s much mileage to be gained from this hybrid strategy.