Simon Willison’s Weblog

Subscribe

Fjax: Just say no

25th June 2006

To my utter amazement, a decent amount of buzz appears to be building around a new “technology” called Fjax—much of it centred around this interview on Webmonkey, but also benefiting from a mention on the O’Reilly Radar and of course the obligatory Digg story.

Here’s the catch: Fjax solves a non-existent problem. Here’s the description from the site:

Fjax is the lightweight, cross-browser, rapid-development methodology for Ajax-style web 2.0 development that puts a Flash engine under the hood (not in the presentation layer—read on) to handle realtime XML/HTML content updating.

Fjax enables web 2.0 development, with true, asynchronous (x)HTML content updating without page refreshes. The trick is, it does it with less than 65 lines of code and works in most browsers. It can process multiple streams of data simultaneously, and has an incredibly small footprint (4K!).

So what does it actually do? It offers a replacement for the native browser XMLHttpRequest object that is slower, less fully-featured and does a bunch of crazy extra work behind the scenes. Ajax requests are instead made through an invisible Flash file that uses Flash to load the data, parse the XML, extract some CDATA and pass it back to JavaScript to replace a div.

Kind of like Prototype’s Ajax.Updater then.

Why would you do this? According to the authors, doing this with JavaScript requires painful code forking. It certainly does if you write JavaScript like they do:


if (document.all) {
  //isIE
  document.all[ThisOutputDivID].innerHTML = objFjax;
} else {
  //isNotIE
  document.getElementById(ThisOutputDivID).innerHTML = objFjax;
}

(The document.all workaround is only needed by IE 4—every subsequent IE version has supported document.getElementById, part of the DOM specification.)

They also claim that using Flash to load and parse XML is substantially faster than the native alternative:

And of course, this stuff is SPEEDY. Vastly reduced code, crazy fast parsing & delivery, quick load/unload, and multiple simultaneous data streams means your final applications have some serious pep.

They haven’t done any benchmarks and I haven’t either—but I would be amazed if this claim held up. Simply sending data between Flash and JavaScript is notoriously slow (see Brad Neuberg’s writeup) and I’ve heard bad thing’s about Flash’s XML parsing speed too. Not that they are really using any of the capabilities of XML—the actual data used to update the page is handed back in one big CDATA block.

The executive summary builds its case on the idea that JavaScript is inconsistent, buggy and slow to develop. Bizarrely, making simple XMLHttpRequest calls (of the kind that Fjax is meant to replace) is one of the few parts of modern JavaScript for which that isn’t true. The following is all the browser-forking code you need to cover every available major browser.

function createXMLHttpRequest() {
  if (typeof XMLHttpRequest != 'undefined') {
    return new XMLHttpRequest();
  }
  try {
    return new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      return new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) { }
  }
  return false;
}

They boast that Fjax uses only 65 lines of JavaScript (plus 4KB of Flash). The equivalent functionality in pure JavaScript, including the above browser workaround, runs to less than half of that:

function ajaxUpdate(url, id) {
  var xmlhttp = createXMLHttpRequest();
  if (xmlhttp) {
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        document.getElementById(id).innerHTML = xmlhttp.responseText;
      }
    }
    xmlhttp.open("GET", url, true);
    xmlhttp.send(null);
  }
}

Another quote:

Using a Flash engine for XML parsing and (x)HTML content delivery reduces approximately 90% of the redundant cross-browser-supporting XML-related code usually associated with standard Ajax development. That in itself is HUGE.

That 90% looks like a rectal approximation to me.

In its present form, Fjax offers absolutely nothing of value to front end developers. Even the idea of using invisible Flash components to make new functionality available to JavaScript isn’t a new one—dojo.storage takes advantage of Flash’s ability to store large amounts of data in an offline cache, while FlashXMLHttpRequest makes cross-domain HTTP requests possible. There’s a lot to be said for using Flash in this way (I’d love to see someone make the Flash accessibility APIs available to JavaScript), but Fjax is not a useful demonstration.

I’m not normally given to debunking crazy technology ideas—mainly because there are so many out there that it would be a full-time job—but this thing is so obviously broken I thought it best to try and nip it in the bud.

One last thing: their technique doesn’t work in either Opera 9/Mac or Konqueror, both of which support vanilla Ajax just fine.

Update: Steve McDonald, one of the Fjax authors, has posted a follow-up comment on the O’Reilly Radar entry. He argues that the getVariable API they are using avoids the performance issues communicating between Flash and JavaScript (I have not verified this) and points out that code-forking for XML parsing is more likely with complex documents (that’s why I like JSON). They have removed the 90% claim from the site.

Previously hosted at http://simon.incutio.com/archive/2006/06/25/fjax