This podcast covers eight patterns on debugging/diagnosis of Ajax Apps, as well as testing Ajax apps, and I’m joined by Craig Shoemaker from Polymorphic Podcast, also a co-author of “Beginning Ajax with ASP.NET”. After some announcements, the interview begans at 6:00. The podcast overall is 60 minutes.

With the series now complete, the podcast will now resume regular Sotware As She’s Developed topics including but not limited to agile development, Ajax, the web, and usability. Also, more conversations – please drop me a line at [email protected] if you’d like to come drop in for a skype chat.

As always, credits on this podcast to My Morning Jacket for the lead-in track, â€œOne Big Holidayâ€. All podcasts in this series licensed under CC.

Audio Note: Sorry about the noise at some stages in this recording – I now know a lot more about audio levelling (the problem of keeping both ends at the same level), but at the time this was recording, it turned out I had set Craig’s end at too low a volume. I used Levelator to level each end, leading to too much noise…next time I’ll need to pump up the volume at each end from the start. I’m also looking forward to resuming use of Bias SoundSoap, but there’s no easy way to get this running on an Intel Mac for now!

The ability to create rich graphics on the fly is one of the critical gaps in Ajax. There are indeed techniques to do it, albeit far from perfect, and some are do-able today if you take a pragmatic view of things and keep graceful degradation in mind.

Here I list all the techniques I can think of to create graphics and images dynamically when you’re creating an Ajax/DHTML/Javascript web app, with varying degrees of portability and usability. Starting with the obvious and ending with the obscure. Please submit any other techniques you’re aware of!!!

Use SVG. Current versions of Firefox, Opera, and Safari (nightly builds) support SVG natively, but with IE and older versions, users need to install a plugin. SVG is an old W3C standard that creates images based on XML. Being a vector format, it stores the image at a high level (curves, lines, etc), so it scales better than a plain bitmap. Here’s an SVG circle (adapted from W3CSchools:

You could build up the XML string in the code or pull it down from the server with a remote request. However, you don’t actually have to specify the XML as a literal string message; you can create a blank SVG document object model (DOM) and manipulate it to build up an image. In this example, we create a circle of radius 25 (adapted from this tutorial):

Where SVG is about things, Canvas is about actions. SVG documents represent images. Canvas tags include code to build up an image, a bit like moving a turtle in the Logo language. So you set a colour, draw something, change the fill style, draw something else, etc. You manipulate a Canvas tag like this:

(BTW Canvas uses the dreaded term, “Context”, to refer to what should really be called “paintbrush”, “pen”, or “turtle” … more concrete terms than “Context” which imply some sort of metaphor. But wouldn’t an imperfect metaphor be easier to grok than the generic “Context”? Alas, it’s a common idiom in graphics programming and will be around for a while.)

Load dynamic images from the server. Once you have an image tag (either in the initial HTML or created on the fly with document.createElement(“img”), you can set its source to any URL, even external to your domain (though cross-domain “hot-linking” should generally be done only with permission). This is standard DHTML/Ajax stuff and works with any browser.

On the server, the image need not be a static image file. It can be a server-side script that happens to output a binary image with the appropriate header, and furthermore, the script can accept CGI parameters, so a unique image can be generated on the fly. Of course, performance will probably suffer if you rely on the server to create images on the fly, and you can only generate them once a second or so. The various Ajax image manipulation tools do something like this.

Use Vector Markup Language (VML). VML is effectively the MS equivalent of SVG, and as such works in IE, and only in IE. As with SVG, you use XML to specify an image.

Embed an XBM file. Yes, some browsers can display XBM images. Works on IE and Firefox, but not Safari or Opera. Unfortunately, XBM has the rather major constraint that it’s black-and-white. However, it does have the virtue of being a plain-text format which, like the data: protocol, you can assign an image source to.

If you get your image data in that format in a string (complete with the
n after each of the #define lines), then you can make any image’s SRC
attribute be:
“javascript:'”+xbmimagestring+”‘”

(Off-topic: I’ve just updated my blog page, I prefer the 2-column sidebar because: (a) there are now 20 monthly archives links; (b) I wanted to add a ton of chicklets; (c) I wanted to add more bio info. BTW If you have a blog, here’s a quick exercise: Place yourself in the mind of a new visitor for twenty seconds, and decide if this person could work out who you are, what you do, and how to contact you. Around 90% of blogs fail this test on the grounds it’s impossible or way too hard.)

I’ve recently been optimising the guts out of a JS webapp I wrote, which was making IE crawl to a halt. I discovered this after introducing a stress-inducing data set. (Using Rails’ fixtures makes light work of this; since the fixtures are Ruby templates just like the web templates, it’s easy to introduce a loop to create lots of data.)

With a rather large data set (100+ items, each several fields), IE would take about 90 seconds to churn through the initial script before the user could do anything. Firefox would run the same thing in about 8 seconds, still too long for a web page, but incredibly about ten times as fast as IE. I’m wanting to avoid pagination at this stage, so first priority was to tweak performance and see if we can keep everything on the same page.

After some sophisticated profiling ((new Date()).getTime():D), the main culprit was revealed to be prototype’s $$. It’s a fantastic function, but if you try to grab all elements belonging to a certain class, and the DOM is really big, $$(“.cssClassName”) can be slow. REALLY SLOW in IE. Remedy:

Removed trivial usages of $$() – e.g. in one case, the script was using it as a simple shorthand for a couple of DOM elements, and it was easy enough to hardcode the array. i.e.
$$(".instruction") becomes [$(“initialInstruction”), $(“finalInstruction”)]. The former notation is cuter, but unfortunately impractical on a large web page.

Introduced the unofficial selector addon. Seems to have improved performance in more complex queries, i.e. $(“#knownId .message”), but doesn’t seem to have affected performance of $$(“.classname”).

Finally, I bit the bullet and scrapped $$(“.classname”) altogether. It’s more work, but the script now maintains the list of elements manually. Whenever an element is added or removed, the array must be adjusted. Furthermore, even the initialisation avoids using $$(), thanks to some server-side generated JS that explicitly declares the initial list of elements belonging to the class (i.e. the list that would normally be returned by $$()). To do this, the following function is called from onload(), generated with RHTML.

The last step explicitly identifies all items in the class, removing the need to discover them by traversing the DOM. I wasn’t really sure how much time it would save – after all, you still have to look the elements up in the DOM and assign them to the array. But when I tried it, the savings were supreme – on IE, from around 45 seconds to about 2 seconds.

I have also incorporated Dean Edwards’ superb onload replacement to get the ball rolling before images are loaded. It’s a neat trick and takes 5 minutes to refactor it in.

Dedicated to the Nitobians, whose last podcast inspired me to crank another one out again. Recent events suggest it may cost me $5000 to appear on their podcast again, and as Andre points out in this podcast, the same applies for them appearing on my podcast. Thus, my simple proposal would be:

Each of us appear on the others’ podcast, at $5000 each. Actually, let’s make that $50k each.

Cancel the debt

Now each of us can claim our podcast attracts guests who pay $50k to appear. Enough to cover headsets ($20), bandwidth ($10/month with Libsyn), and assorted beverages (name your price).

…

Profit!!!

Soon I’ll be publishing the final podcast in the overall series, which has already been recorded, and then I’ll be taking it in a more general direction akin to the topics on this blog – talking about agile, programming (Java/Rails/etc), usability, Web2.0, as well as Ajax and the coming revolution of real-time webapps. If you have a skype account and you’d like to join me sometime, drop us an email ([email protected]). Also feel free to suggest any topics that would be good to cover.

I’m asking guests to join me for most of the remaining Ajax Pattern podcasts. Seeing patterns from someone else’s perspsective will make the discussion richer and hopefully cover more questions you might have as you’re listening to the podcast. The guest for this week is Andre Charland of E-Business Applications, widget guru and author of the upcoming Enterprise Ajax book.

The fourth and final podcast in this series of Ajax Programming Patterns. As always, the patterns are online at AjaxPatterns.org and covered in the book too, now available at Amazon. This 33-minute podcast covers seven patterns of Performance Optimisation:

(Note that the last two are recent additions to the wiki and just stubs at this stage.)

Okay, here endeth the series. I will soon be starting up a new series on the next group of patterns (Part 5 in the book): Functionality and Usability Patterns. There will be a change in the format, one I hope you’ll enjoy!

The third podcast in this series of Ajax Programming Patterns. The 29-minute podcast covers five patterns. As with the previous podcast, there is reason for concern about the audio quality herein. Firstly, three patterns on DOM population – taking server response data and displaying it or storing it in the DOM:

Share this:

G’Day

Welcome to Michael Mahemoff's blog, soapboxing on software and the web since 2004. I'm presently using HTML5 and the web to make podcasts easier to share, play, and discover at Player FM. I've previously worked at Google and Osmosoft, and built the Ajax Patterns wiki and corresponding book, "Ajax Design Patterns" (O'Reilly 2006).
For avoidance of doubt, I'm not a female, nor ever have been to my knowledge. The title of this blog alludes to English As She Is Spoke, a book so profoundly flawed it reminded me of the maturity of the software industry when this blog began in 2004. I believe the industry has become more sophisticated since then, particularly the importance of UX.
Follow @mahemoff