Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Fjax: Just say no

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.

This is Fjax: Just say no by Simon Willison, posted on 25th June 2006.

Tagged , , ,

View blog reactions

Next: Notes on JavaScript Libraries

Previous: Two revolutionary features in Opera 9

27 comments

  1. I was wondering what the point of Fjax was!(if any). Thanks for saving me the time.

    Andrew K. - 25th June 2006 23:17 - #

  2. Yet another example of people blaming the result of their ignorance on one tool so that they can use their favourite tool instead. It's nothing new, it used to be quite common with CSS versus table layouts. Remember the "CSS can only create boring-looking designs" myth? If it wasn't for the CSS Zen Garden comprehensively demolishing that argument we'd probably still be arguing against it today.

    Jim - 26th June 2006 00:46 - #

  3. I could possibly see the point if they were doing it for a persistant socket connection for something instead of polling, but just for a XMLHttpRequest is kind of mind boggling. So now you have an extra level of code on top, which requires something else to be installed (ok, Flash's penetration level is good, I'll give you that) which gets you no benefits from what I can see?

    Richard Livsey - 26th June 2006 00:49 - #

  4. Hi, the bug Brad Neuberg references on the site you mention has been fixed :) Performance should be excellent. I think now with Flash Player 9, one will see significant performance advantages over the browsers JavaScript engine because the VM is Flash now has a JIT and many other performance advantages. Also, we now support the latest (not yet ratified) ECMAScript 4 (aka JavaScript 2) including E4X and this is a nice syntax for handling XML. That said, I am not sure if this Fjax makes much sense in and of itself. I think it things like dojo.storage make more sense as they take advantage of features of Flash that don't exist in the browser container. I like how google is using Flash and JavaScript to tie their financial charts to news headlines (Google Finance). And I think we will see a lot of folks using the FJax idea, but not for XML (which the browser/JS can handle) but for binary data which the browser can not (Flash Player has binary socket support as well as XML socket support...as well as HTTP, RTMP...). -David Adobe

    David - 26th June 2006 01:38 - #

  5. Maybe it was a joke? Nah. Someone actually thought it was going to take off. Meh.

    Dustin Diaz - 26th June 2006 02:58 - #

  6. Great write-up, and while it would be a full-time job outing all the crap that is out there, I think someone needs to start because there is far too much of it.

    Colin D. Devroe - 26th June 2006 03:27 - #

  7. I think now with Flash Player 9, one will see significant performance advantages over the browsers JavaScript engine because the VM is Flash now has a JIT and many other performance advantages.

    David, I suggest you take a step back and take a look at the big picture. You are talking about communicating with a server across a network. No amount of JIT will make that faster. The CPU is not the bottleneck when it comes to making Ajax requests.

    Jim - 26th June 2006 04:15 - #

  8. Maybe this could be a solution for cross-domain XHR? Although, it looks like there are efforts underway to "fix" that problem without Flash.

    Mark Finkle - 26th June 2006 05:57 - #

  9. I agree, if you're going to use an invisible Flash object, at least use it to do something that browser's don't support.

    For example, you can do cross-domain requests (GET and POST only for now) with FlashXMLHttpRequest.

    Flash can also do client-side storage (AMASS, dojo.storage, Flash4AJAX), canvas-style operations (AFLAX) and XML sockets.

    Julien Couvreur - 26th June 2006 07:18 - #

  10. The other missed point is having your server return xml and munging it into HTML on the client. If you return HTML instead, you can do it in a tiny amount of javascript, as I pointed out with JAH and AHAH

    Kevin Marks - 26th June 2006 07:28 - #

  11. Kevin: Of course, I'd forgotten about AHAH - that's a better example than Ajax.Updater.

    Simon Willison - 26th June 2006 10:54 - #

  12. That 90% looks like a rectal approximation to me.

    LOL! I must use that phrase when next confronted with bogus statistics.

    Gerv - 26th June 2006 11:59 - #

  13. As the saying goes, just because you can, doesn't mean you should.

    Duncan Gough - 26th June 2006 14:23 - #

  14. Thanks for clarification. "Eliminate the middle man" still seem to be a good idea ;) P.S. "rectal approximation" is brilliant, I keep improving my English skills;)

    Vlad - 26th June 2006 19:14 - #

  15. Hi, "David, I suggest you take a step back and take a look at the big picture. You are talking about communicating with a server across a network. No amount of JIT will make that faster. The CPU is not the bottleneck when it comes to making Ajax requests." Correct. Didn't mean to imply otherwise (nor was I asserting fjax was a good approach). The potential performance gain is in the parsing of XML, not in the network speed. -David

    david - 26th June 2006 20:08 - #

  16. Man, some of my friends at work and I thought of this like a month ago (it became kind of a running joke), but we added the idea of using PHP somewhere in there (never really figured that part out) and had a way better accronym: FLAPJAX!

    Greg Hinch - 26th June 2006 21:08 - #

  17. Thank you for pointing this out. I love it when something sounds too good to be true is debunked. I do wonder if the core ideas here can be worked into a better model for dynamic site creation though... behind the scenes flash as a way to pull a different video each time, and backend load transitions and ads would be very cool indeed.

    Jessica - 27th June 2006 06:51 - #

  18. We went mad when we saw that authors got such a huge attention by solving, as Simon said, a non-existent problem. So we decided to make a framework of our own that actualy did something usefull. It is called SwfJax and it is a full replacement of XMLHttpRequest object with xPath addressing capabilities.

    Check it out at http://www.incito.lt and tell us what you think!

    Paulius Uza - 27th June 2006 11:03 - #

  19. Simon - The claim about +90% of the internet using Flash 6 is correct. I have not looked at the 'speed' of Flash 6 XML performance, but FJAX is using flash 6 code. With Flash 8 and soon to be Flash 9 plugin to be out in a couple months, it is a same bet that this minumum requirement of the Flash 6 plugin give them alot a high percentage of the internet. By any stretch of imagination, more the JavaScript with it turned off.

    Patrick Whittingham - 27th June 2006 19:04 - #

  20. Patrick: I'm not disputing the Flash market share statistic (I don't mention Flash market share anywhere in my entry). The 90% statistic I'm objecting to is the "reduces approximately 90% of the redundant cross-browser-supporting XML-related code" one.

    Simon Willison - 27th June 2006 19:48 - #

  21. I would not use Flash to replace Ajax style code, but there are some interesting possibilities when doing networking with hidden Flash:

    1. Use Flash's multiplexing streaming - this would come into use if you are doing synchronous, realtime collaboration in an Ajax application, such as real-time editing of some document in the browser ala SubEthaEdit. Flash's multiplexing streams are designed so that no one in the collaboration gets "resource starved"; data is transmitted in fixed size chunks, so no one can overload the channel and get squelched. This might theoretically make it possible to create Ajax collaborative apps that can scale to many more people at one time versus what is possible with Comet or server push.
    2. Use Flash's low-level sockets - Flash has client-side sockets, making it possible to roll your own IRC server, etc.
    3. Use Flash's cross-site scripting - Julien Couvreur has done this to good effect.

    If you don't have one of these specialized requirements, just use XHR :) It's alot simpler. Even better, use Dojo IO.

    By the way, if anyone wants to expose these to Ajax, you can use the Dojo Flash library I created that solves the performance and reliability problems pointed out in this blog post. That's what Julien did with his cross-site service framework and what I do with Dojo Storage.

    Best, Brad Neuberg

    Brad Neuberg - 27th June 2006 22:48 - #

  22. I wonder if there is not a cultural component to this. I've started hacking in actioncript (still my main job) around 2001. At that time there were few js libraries that abstracted cross-browser issues. On top of that older browsers were still hanging around (ie 3, ie 4) which made this some what worse. Point is, among flash developers (of course many know better, but still) the myth that javascript is buggy and unreliable.

    Also, there is another intesresting issue here. Macromedia has been pushing hard on the idea of ria apps with flash. The idea is simple: it's much easier to develop very interactive apps through flash (real time input feedback, no page refresh, xml parsing etc..). As an actionscript developer, I am moving more and more towards javsacript. It's easier to degrade gracefully, it's serachable and honestly, anyone who has worked with flash components know they are buggy and just uglly, nevermind the horribly inconsistent api.

    As js toolkits add better widgets, flash ria will become irrelevant. Right now flash has two great things going for them: 1) great video codec with large userbase and small download. 2) the new file upload capability. It seems macromedia's dream of full flash ria are becoming dust. What we will see is lots of javascript with small flash pieces (video players, uploaders...)

    cheers arthur

    arthur debert - 27th June 2006 22:52 - #

  23. I wish Dojo Storage would get this kind of high scale attention on O'Reilly and other sites; I've spent the last year architecting it to be fast, compatible, reliable, and easy to use. Plus, I did it all for free and made it open source. I believe Dojo Storage holds the possibility of transforming the kinds of web apps we can build, as opposed to Fjax which is re-rolling the wheel. Imagine storing hundreds or megabytes of data on the client-side in a secure way with the user's permission, across 97% of the existing installed base. You can create offline apps with this, use it to create highly reliable business applications that journalize all of their server requests in case the network goes down, improve performance with client-side caching, protect private documents and spreadsheets by saving them locally rather than on a server, use it to save public and private key information for highly secure apps, and more. I just spoke at eBay about it last week and they are excited about the possibilities.

    Brad Neuberg - 27th June 2006 22:53 - #

  24. Well, for me the site was pretty much broken.

    Robert Wellock - 28th June 2006 18:35 - #

  25. Simon - which browser combinations would you expect to have trouble with your sample code? Where would you expect to find problems. I tested it with the latest Opera, Netscape, Explorer and Firefox and it worked fine. It didn't seem to work in Opera 7 on a PC.

    rob - 1st July 2006 22:52 - #

  26. Rob: My example code should work on any browser that supports the XMLHttpRequest object. Opera didn't get XMLHttpRequest until Opera 7.60.

    Simon Willison - 3rd July 2006 08:28 - #

  27. Fjax should not be mixed with Fajax which is a nice IE display trick.

    splintor - 5th July 2006 12:13 - #

Comments are closed.

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

A django site