I’ve been putting together some AJAX design patterns.
Update (May 15, 2005): I’ve set up AJAXPatterns.org to keep working on these patterns. I’ve also cleaned up a couple of things here, although all future changes will occur at ajaxpatterns. Thanks to Leoglas for spotting two errors here.
AJAX holds a lot of promise for web usability, and the underlying technology has already delivered some stunning applications. But it’s no magic bullet. Careful design is always required, and it must be based specifically on the technology at hand. As AJAX emerges, we’re going to learn more about what sort of design works, and we’ll need ways of documenting this information and talking about it. Fortunately, the evolution of this particular technology will take place at a time when design patterns are well-entrenched in the industry, and design patterns are an excellent means of knowledge representation. Thus, it makes sense to begin cataloguing AJAX design patterns. These are some thoughts based on current examples and demo systems.
Patterns being patterns, there’s not a lot of unseen information here. Patterns are just a concise way to represent the knowledge embodied in the many AJAX applications that are out there. The point is to discover best practices by investigating how developers have successfully traded off conflicting design principles. AJAX is all about usability, so the patterns focus particularly on delivering usability in the face of constraints, most notably: user capabilities and expectations, bandwidth limits, the stateless nature of HTTP, the complexity of Javascript.
This is a work-in-progress. There should eventually be more patterns, more examples, more detailed explanations. And one more disclaimer: AJAX is a new term, but XMLHttpRequest and related technologies have been around for a while. I know that, but the introduction of a single umbrella term nevertheless constitutes a tipping point which is forcing web development to move heavily in a certain direction. AJAX is only a name, but names can be tremendously important.
Thomas Baekdal’s AJAX Usability Guidelines contains some great advice and inspired me to write these patterns. What I’m doing here is not just stating different guidelines. Patterns ain’t principles, and the focus here is on patterns whereas the focus above is on principles. Both forms of design advice are vital. Here, I’m explicitly distinguishing between the two, because the patterns are intended to help designers achieve the principles. The principles here are heavily influenced by Baekdal’s guidelines.
fiftyfoureleven.com and AJAX Matters contain great collections of AJAX examples. You can’t have patterns without examples.
Joel Webber illuminates the technology behind Google Maps. Chris Justus dissects Google Suggest.
The recent AJAX podcast and blog entry covered some of the strengths and weaknesses of AJAX. The patterns here are supposed to guide on emphasising the strengths of AJAX without being struck by its weaknesses. The Polymorphic Podcast has also covered AJAX - prior to my podcast and is recommended as alternative overview on the technology.
Some (and eventually all?) of these principles above inform the patterns below. The patterns are about trading off among the principles, and also about resolving conflict between the needs of usability and other practical constraints, such as ease-of-development.
Local Event-Handling You want the user experience to be dynamic and responsive, but it slows things down if you have to keep going to the server. THEREFORE, ensure most events are handled locally, resorting to server-side interaction only when there is no local facility. To increase the cases where local handling is sufficient, consider using Local Caches.
Local Cache You want to support Local Activity, but many events must be handled by resorting to data on the server. THEREFORE, maintain a local cache of information. The cache might be created on initialisation or accumulated after each query. When accumulating upon query, it’s probably worthwhile performing a predictive download.
Predictive Download You want the application to respond quickly, but many user actions will require information from the server. THEREFORE, anticipate likely user actions and pre-load the required data. Note that this auxiliary information should ideally be downloaded after the main information has been loaded. A “background thread” might even be used to continuously monitor the user’s local behaviour, regularly pulling down information which might be useful.
Submission Throttling You want the application to respond quickly, but it will be overloaded if the server was accessed for every trivial input event. THEREFORE, instead of submitting upon each Javascript event, use the events to change local state. Store events in a buffer variable, or some DOM component, and frequently (e.g. once a second) poll to see if anything should be submitted. As a variant to periodic polling, check the time since last submission whenever a new Javascript event occurs. Note: If the period is long (e.g. 10 minutes), show the Synchronisation Status and consider allowing explicit submission as well.
Explicit Submission (An alternative to Submit Throttling.) You want the application to respond quickly, but it will be overloaded if the server was accessed for every trivial input event. THEREFORE, instead of submitting upon each Javascript event, require the user to explicitly request it, e.g. submit upom clicking a button. Ensure the user knows what’s been submitted with Synchronisation Status.
Periodic Refresh You want the browser to be synchronised with the server, but information may change server-side after the user last made a change (e.g. because of another user on the same system). THEREFORE, the browser should periodically call the server so as to refresh any volatile information. Furthermore, indicate information staleness is with Age Displays.
Distinct URLs You want to let users send and bookmark information, but the application is dynamic and the results of XMLHttpRequest interaction will not alter the URL. THEREFORE, use a URL-based scheme or write distinct URLs whenever the input will cause a fresh new browser state, one that does not depend on previous interaction.
Rich CSS You want the user-interface to be rich and colourful, but you have to minimise download size in order to make the interface responsive. THEREFORE, lean heavily on CSS to give a rich, graphical, appearance, without having to download images.
Rich CSS You want the user-interface to be rich and colourful, but you have to minimise download size in order to make the interface responsive. THEREFORE, lean heavily on CSS to give a rich, graphical, appearance, without having to download images.
Rich CSS You want the user-interface to be rich and colourful, but you have to minimise download size in order to make the interface responsive. THEREFORE, lean heavily on CSS to give a rich, graphical, appearance, without having to download images.
Embedded Text You want the-user interface to be rich and graphical, but you need plain text in order to support standard web functionality such as cut-and-paste and inspection by search engine robots. THEREFORE,integrate text into graphics, and rely on Rich CSS to show text when fancy styling is desirable.
Age Display You want the user to trust the system, but it’s possible some information on the browser is stale. THEREFORE, indicate the age of any critical information. Vary background brightness, for instance.
Synchronisation Status You want the user to rely on the system to capture the input, but not all input is immediately submitted because you are using Submit Throttling or Explicit Submission. THEREFORE, provide hints that indicate what’s synchronised and what’s pending. For instance, use a different background colour on text fields. This is important if you are using Explicit Submission or Throttling with a long period.
Nothing new here. All have been available in desktop GUIs and some in non-AJAX DHTML too. This is really just a catalogue of interaction styles that are becoming common idioms in AJAX applications and can benefit from XMLHttpRequest-driven interaction.
Drag-and-drop e.g. This demo
Popup data input
Popup information
Highlighting e.g. A9’s customisation feature highlights search plugins you select them.
Drilldown e.g. Betfair’s Sidebar Menu.
Auto-Completion Most famously, Google Suggest.
Browser-Agnostic Components You want to make the system interactive with sophisticated DHTML, but portability can suffer. THEREFORE, encapsulate units of DHTML activity into browser-agnostic components. A “component” may simply be a Javascript function with a bunch of if-statements, or a factory in an Abstract Factory hierarchy, or a server-side, Javascript generation object.
Server-Side Code Generation You want to make the system interactive with sophisticated DHTML, but sophisticated DHTML can be difficult. THEREFORE, use a server-side framework to generate the HTML and associated Javascript. Note that this pattern will become more useful as frameworks emerge.
Server-Side Code Generation You want to make the system interactive with sophisticated DHTML, but sophisticated DHTML can be difficult. THEREFORE, use a server-side framework to generate the HTML and associated Javascript. Note that this pattern will become more useful as frameworks emerge.
… which will emerge as patterns.
I’m interested to hear what people think. Leave a comment or send an email to michael@mahemoff.com.
You forgot to explain “Synchronisation Flags”? At least I’m not sure what you mean and can’t find it.
And google maps does keep an exact link available to the position your are looking at, (even after scrolling), that also includes your search terms! It’s at the right, ‘link to this page’. I used to be bugged (always linked to 1 zoom level higher then the one you had set) but that has been fixed.
May 8th, 2005 at 11:00 am. Permalink.
Hi Michael,
Very interesting article and an excellent read. I do agree with the majority of your thoughts/guidelines.
The things that are really interesting about this, is that each individual item is not that special. It is the combination that makes it brilliant. This is also why I like your patterns. Developers could pick a number of elements, combine them and make something really spectacular.
XMLHttpRequest does and should rely heavily on client-side interaction and cache, but it needs two important things.
1: The ability to work in separate work-threads, that is, client-side applications are really not good at multitasking. It is very hard to make you client side application do two or more things at the same time.
2: Failure protection. By this I do not mean making sure the script works, but what if the user has used this for sometime. He has changed a number of things and then suddenly closes the browser? Well, if the application relies on client side cache then all the work is lost. This would be catastrophic, especially when web-applications become more advanced.
Normal applications either stores the current state, allowing the user to get right back where he was - or alerts the user “are you sure you want to destroy all your hard work?”. Hardly any web-applications remember this. PS: if you can, do without the alert box, just save the users active state.
May 11th, 2005 at 9:30 pm. Permalink.
Legolas,
Thanks for the feedback. Synchronisation Flags is a typo and should be “Synchronisation Status”. Google maps link is indeed there: how could I have missed it? An interesting alternative design would be to actually show the URL on the page. However, it would probably be overly distracting. For the sake of RSS subscribers, I’m trying to avoid too many updates, but I’ll add it shortly. I’m in the process of creating a separate site to host these and other patterns (ajaxpatterns.org), so I can update at will.
Thomas,
Glad to see this got back to you. While I’ve shied away from calling it a language at this stage, I think the interconnections are the true power behind any collection of patterns. So I’ve tried to emphasise how developers have been - or could be - combining different aspects of AJAX.
Multitasking - and performance in general - may well be one reason to resort to the server, especially with the increasing trend of grid computing.
Failure protection, likewise, is definitely an issue, and compromises must be made pragmatically. One thing that immediately comes to mind: The Local Cache pattern ought to distinguish between write caching, which is vulnerable to crashes, and plain old read caching.
Saving state is interesting. AJAX-style applications should actually be able to prevent many of the disasters caused by users quitting the browser. Not always, by any means - as browsers can crash or the computer can be shut down. It just shows that developers need to take that into account in designing the breakdown between browser/server work. ie How long might a typical user be working on the browser without any updates? If a long time, maybe an Auto Backup facility is required, which would upload changes, just like on standard editors/word-processors.
May 11th, 2005 at 10:27 pm. Permalink.
[…] ando flash per passare ad ajax anche lo loro (giustamente?) lo chiamano dhtml. [update 3] programmazione per pattern usando ajax e relativo wiki ciuaz
Questo messag [...]
May 15th, 2005 at 12:37 pm. Permalink.
[…] ando flash per passare ad ajax anche lo loro (giustamente?) lo chiamano dhtml. [update 3] programmazione per pattern usando ajax e relativo wiki ciuaz
Questo messag [...]
May 15th, 2005 at 1:05 pm. Permalink.
[…] s opens up all sorts of user interface opportunities. Michael Mahemoff writes more about Ajax and the User Experience. As cool as this is, I haven’t seen much muttering about this in the […]
May 19th, 2005 at 9:16 pm. Permalink.
[…] Harper @ 12:14 am An interesting link I found on del.icio.us– AJAX Patterns: Design Patterns for AJAX Usability. I haven’t used AJAX for anything at all thus fa […]
May 20th, 2005 at 7:16 am. Permalink.
[…] g fertig haben… Hier noch ein paar interessante Seiten/Artikel: www.ajaxmatters.com AJAX Patterns www.ajaxian.com This entry was posted on Friday, May […]
May 27th, 2005 at 6:48 pm. Permalink.
[…] ween the two. ~ joshua porter - uie del.icio.us ajax, wikipedia ajax, ajax patterns from this guy, and a resource of ajax matters
interface design July 15th, 2005 at 9:26 am
[…]
July 15th, 2005 at 6:52 pm. Permalink.
[…] ming usability: XMLHttpRequest Usability Guidelines Usable XMLHttpRequest in Practice AJAX Patterns: Design Patterns for AJAX Usability The Hows and Whys of Degradable Ajax Getting data f […]
October 8th, 2005 at 6:41 pm. Permalink.
[…] sp http://www.lukew.com/resources/articles/ajax_design.asp http://www.lukew.com/ff/entry.asp?183 http://www.softwareas.com/ajax-patterns http://scottwater.com/blog/archive/2005/05/25/cojax http://www.lukew.com/ff/entry.asp?186 http://weblog.inf […]
October 29th, 2005 at 3:45 am. Permalink.
I’m just becoming familiar with AJAX and have two issues that I wonder if you’ve got suggestions for. 1) How to prevent someone from using the URL in a XMLHttpRequest for their own purposes, basically robbing me of functionality? 2) If I have transformed XML into an HTML page and want to reuse that XML document with JavaScript inside the transformed HTML without making an additional server call (XMLHttpRequest), is there a way to do it?
Thanks in advance for any ideas you have.
– Michael
November 4th, 2005 at 6:17 pm. Permalink.
MichaelR,
(1) Well I guess the standard “Web 2.0″ response would be “Just share it with the world and gain MINDSHARE“. But if you don’t buy that, consider a combination of things: strict legal notice, tracking by referrer and IP number and cookies (if someone hasn’t visited your site, why are they calling your web service?), email authentication, CAPTCHA authentication.
(2)You can add the XML document as a node of an XHTML doc, if that’s what you’re getting at. See http://ajaxpatterns.org/XMLDataIsland.
November 6th, 2005 at 5:06 am. Permalink.