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.
Andrew K. - 25th June 2006 23:17 - #
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 - #
Richard Livsey - 26th June 2006 00:49 - #
David - 26th June 2006 01:38 - #
Dustin Diaz - 26th June 2006 02:58 - #
Colin D. Devroe - 26th June 2006 03:27 - #
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 - #
Mark Finkle - 26th June 2006 05:57 - #
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 - #
Kevin Marks - 26th June 2006 07:28 - #
Simon Willison - 26th June 2006 10:54 - #
Gerv - 26th June 2006 11:59 - #
Duncan Gough - 26th June 2006 14:23 - #
Vlad - 26th June 2006 19:14 - #
david - 26th June 2006 20:08 - #
Greg Hinch - 26th June 2006 21:08 - #
Jessica - 27th June 2006 06:51 - #
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 - #
Patrick Whittingham - 27th June 2006 19:04 - #
Simon Willison - 27th June 2006 19:48 - #
I would not use Flash to replace Ajax style code, but there are some interesting possibilities when doing networking with hidden Flash:
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 - #
arthur debert - 27th June 2006 22:52 - #
Brad Neuberg - 27th June 2006 22:53 - #
Well, for me the site was pretty much broken.
Robert Wellock - 28th June 2006 18:35 - #
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 - #
Simon Willison - 3rd July 2006 08:28 - #
splintor - 5th July 2006 12:13 - #