Flash vs. Ajax

I’ve been hearing a lot of Flash vs. Ajax arguments lately, and unfortunately, they almost always start off in the wrong way.

It’s very common to hear people argue about Flash websites or RIAs vs. Ajax websites or RIAs, but this is always the wrong way to approach building any website. Would you have an argument with an architect about whether to build a house out of wood vs concrete? Of course not, they would use each material to build the parts of the house that the respective material is best for. Sometimes you might want to build a shack or barn out of all wood, sometimes you might want to build an all brick house, but many times you’ll want to use the best material for each section of the house. Build the foundation out of concrete, the walls and roof out of wood.

Websites and web applications should be treated the same way. Break things down to a component level and go from there. Use the right tool for each component. If you can do it well with HTML/Javascript, go for it. If it would work out better with Flash, then why waste time recreating something with Javascript that you could build 3 times faster with Flash? There are plenty of great examples of this today around the internet:

One of my favorite examples is Google Finance. They use HTML and Javascript for the stuff that is best suited for that, and then when they need to show a nice graph, they drop in a great interactive Flash graph and talk to it using Javascript as needed. The Flash controls the Javascript, and the Javascript can control the Flash as needed.

Another example is Flickr. They started out using Flash to display all of the images, including the image notes and the other toolbar options along with each image. While this might have been a good choice as the site started out, it was soon replaced by a more efficient HTML version of the toolbar and notes system that works just as well as the Flash version. They did end up keeping one small bit of Flash so users can rotate images and see a preview before they save it.

So the next time you start planning a website and you start thinking: “Hmm, Flash or Ajax?” Instead of looking at it from a site-wide perspective, try thinking about your site as a series of components, and then choose Flash or HTML/Javascript for each individual component instead.

How accessible is your Flash embed?

There’s an interesting article over on the Macromedia Accessibility blog. They take a look at some popular Flash embed techniques and see how they perform in screen readers. The thing that caught my eye, though, was the performance of the Flash Satay embed method. It looks like if you are using Flash Satay, JAWS won’t read your Flash content.

Unfortunately, they didn’t test FlashObject, but they did test UFO – which works in a very similar way – so I think it’s pretty safe to say that they would behave the same way in a screen reader.

Proper Flash embedding: FlashObject Best Practices

UPDATE (7-24-2005): This page refers to an old version of the FlashObject script. For questions or comments, or to download the script, please refer to the permanent home of the FlashObject script.

This post is a continuation of a previous post. Read this for more background information on the FlashObject embed method.

In the months since I posted the FlashObject embed I’ve had a chance to talk to a number of developers and use it in a few high traffic projects. In doing so I’ve picked up some tips and best practices that I’ll be outlining here. I’ve also revamped the FlashObject script so it’s a bit more light weight and fixed a few small bugs.

What’s new?

  1. Alternate content is no longer written to the page by default – You may still use the fo.altText variable to add alternate content to your pages, but it is not recommended. The way to display alternate content in your pages with Flash content would be to place the alternate content on your page, and then specify the ID of the element with your content inside. The FlashObject script then writes your Flash content inside that element, replacing your alternate text/content so the end user with Flash will never see it, but users with no Javascript or without the required Flash version will see the alternate content. Google will also index your alternate content since it is just plain HTML.

    Here is an example of what your embed should look like:

    <div id="flashcontent">
      Place your alternate content here and users without the Flash plugin 
      or with Javascript turned off will see this. 
      Include a link to <a href="?detectflash=false">bypass the detection</a> 
      if you wish.
    </div>
    <script type="text/javascript">
     // <![CDATA[
      var fo = new FlashObject("fo_tester.swf", "fo_tester", "300", "150", 6, "#336699");
      fo.write("flashcontent");
     // ]]>
    </script>

    Because of this change, you should always specify the ID of an element to write your Flash content into. You should also be sure to always include alternate content on the page. If your Flash movie is purely decorational, you can leave the div empty, similar to using empty alt attributes (alt="") on decorational images. Also note that with the new version you need to place your Javascript that writes the Flash content after the element that will contain your Flash content, as in the example above.

  2. Support for pulling variables from the URL string when using anchors – There have been some discussion about Flash state tracking and direct or ‘deep linking.’ Most of the methods rely on parsing variables from the URL when the movie loads, so now you can pull vars out using the built in function getQueryParamValue().

    Example:

    If your URL is:

    flashobjectpage.html#var1=value1&var2=value2

    You can pass those vars into your Flash movie by using the following code:

    var fo = new FlashObject("fo_tester.swf", "fo_tester", "300", "150", 6, "#336699");
    fo.addVariable("var1", getQueryParamValue("var1"));
    fo.addVariable("var2", getQueryParamValue("var2"));
    fo.write("flashcontent");

    The same works for normal URL parameters in URLs such as:

    flashobjectpage.html?var1=value1&var2=value2

Just to recap some of the things posted in the previous FlashObject post, here’s some of the thinking behind the FlashObject embed method:

Why Javascript?

Javascript is the best overall solution for a number of reasons, among them:

  1. With Javascript you can detect the presence of the Flash Player on your user’s system and either display the Flash content or leave the existing (X)HTML on the page. This is also a huge advantage when it comes to search engine indexing since the alternate content is on the page and will be indexed as normal content. This also prevents novice users from seeing Internet Explorer’s ActiveX install box, which on Windows systems pre-SP2 is a very scary thing these days with all the Spyware and Malware running around on the internet. On most other browsers, you’ll likely see some empty box where the Flash content should be, sometimes with a broken image or puzzle piece icon which most novice users have no idea what to do with (Should they click on it? Is it part of the site?). If you include well written upgrade/install instructions in your alternate content, all of these problems are avoided.
  2. No Extra configuration files for each Flash movie. Some alternate methods of embedding Flash content in XHTML documents include using extra configuration files or ‘holder’ movies that load in other movies. With this method there is no need for any extra files aside from the single .js file.
  3. Easy to serve different content to different browsers. I worked on a project recently that made extensive use of the wmode=transparent option. Well when you are using IE or Firefox you can use wmode=transparent with the Flash 6 player, but if you are using Apple’s Safari browser, you need Flash player 7 to see the content properly. So in the embeds on the page, we required Safari users to have the Flash 7 player, and everyone else the Flash 6 player. Without Javascript we would have had to force everyone to upgrade to Flash player 7, something we didn’t want to do, even though the Flash 7 player has a pretty high penetration percentage.

Problems with Flash Satay/pure Object tag embedding

The main issue with using any embed method that uses only object tags to embed any plugin on a page is that Safari ignores the param tags. For very basic embeds this isn’t a problem, but when you want to start passing in variables or change the background color of the movie without re-publishing it you start to run into problems.

The one area where using pure object tag embeds shine is in using XHTML pages that are sent with a mime type of application/xhtml+xml. Since the FlashObject script uses innerHTML and sometimes document.write, it is not compatible with pages sent with the application/xhtml+xml mime type. Currently I have no plans to update it to work with these pages, as there are many issues with creating object tags using the DOM because almost every browser engine handles it differently and has little quirks that make it very hard to work around. If you are interested in seeing some of the code it would take to embed Flash in XHTML documents, check out the excellent Javascript that comes along with sIFR 2.0.

Download

Download the source to FlashObject 1.1.1.

Download the source to FlashObject 1.3.

View sample pages using FlashObject 1.2 in different Flash embed situations.

UPDATE (5-5-2005): If anyone is interested, Paul Newman has wrapped this script into a Dreamweaver extension. It costs $15 (or free to CommunityMX subscribers), but if you are a not-so-technical Dreamweaver user I think it would be worth it.

UPDATE (5-17-2005): Made a small change to the embed tag output. I changed the id attribute to a name attribute as Firefox needs it that way in order to use LiveConnect and talk to the plugin via Javascript.