News: Developing Ajax Applications That Preserve the Back Button
BEA's dev2dev site has published an article Mark Schiefelbein by entitled "Developing Ajax Applications That Preserve Standard Browser Functionality," that discussed the use of the browser's back and forward buttons, among other things, with a focus on the BackBase engine and how it provides support for common browser functionality.
- Posted by: Joseph Ottinger
- Posted on: January 27 2006 10:50 EST
It starts off with a discussion of how AJAX applications are fundamentally different than traditional web applications by discussing "rich" applications vs. the "reach" of applications, and how AJAX is enabling applications to have both "reach" (meaning that they're accessible by browsers, over the web) and "richness" (meaning with a level of client interactivity not normally implemented by traditional simple web applications implemented via pure HTML.)
Mr. Schiefelbein then discusses the idea behind tracking state changes in AJAX applications - i.e., interactions that would yield a unique URL that would be suitable for bookmarking, or navigation "forward" or "back."
After a display of code that implements url manipulation (yielding URLS for bookmarking), he walks through a case study with the BackBase engine, which implements much of the required functionality out of the box.
- Developing Ajax Applications That Preserve the Back Button by Paul Strack on January 27 2006 12:43 EST
- Easy with the history list by Michael Jouravlev on January 27 2006 13:31 EST
- Developing Ajax Applications That Preserve the Back Button by Jacob Hookom on January 27 2006 14:05 EST
- Back button - really useable? by Aaron White on January 27 2006 22:37 EST
If you application needs back/forward button support, I have to question whether Ajax is the right technology to use to build your application. After all, if you need the back button, you probably also need book-marking, and may as well build your application as a traditional, page-based web app where (almost) all your content is generated server-side. That way you know you will be able to reconstruct the client-state entirely from your URL.
I think Ajax is more suitable for building fat-clients that run in the browser. They should support the traditional undo/redo/save paradigm used by desktop applications instead of the browsing paradigm of the web, which is equally familiar to most computer users. Integrating your fat-client behavior with the browser's back/forward/bookmark/refresh behavior is asking for trouble.
I might change my mind if there was better support for this in current browsers, but all the back-button AJAX integration techniques I have seen are pretty ugly hacks.
I agree that some level of history list navigation is needed for Ajax apps. (History list navigation includes support not only for Back button, but for Forward button as well.) At the same time I think that history list in a web application(not just in Ajax applicaiton) should be as short and simple as possible.
From the article: “In the traditional model every page refresh resulted in a URI update” — Not true.
[Re]loading a page does not have to cause URL change. As the article shows, changing URL does not have to cause [full] reloading of a page. Therefore the notion of a single-page web experience needs to be refined. We have to draw a line between single-load interface and single-address interface.
Adding every visited resource to a history list works well for hyperdocuments but usually a nuisance for web applications. There is a way to get rid of this behavior using redirection to the same address. Ajax provides the same user experience for free, great, use it! Instead if it, people try to reimplement hideous history list in Ajax. Incredible.
Don’t get me wrong, I am all for proper page reload and for navigating back and forth, but only when it makes sense! Say, you have a menu on a webpage. You select one item, than another, then another. Should all three actions be recorded as three locations in history list? Should I click Back three times to leave the page with the menu? Come on, this is ugly.
Take first example from article: the value in combobox is changed, and this event is recorded in history. Are you kidding? Why the hell do I need a stupid item change in my page history? I reselected an item five times, now I need to click five times Back to leave the page? No way! I understand that this is only an example, but get real, use sensible examples.
For example, a form submission. If I made five attempts to submit a form, should I click back five times (sorry, six times) to leave the form? Would not it be easier to click only once? Each form submission is an attempt to submit the *same* page! Does someone want to explicitly stick all five submissions into history list?
Take his second example from the arcticle, the discussion forum, taken right from Backbase website. I can see the justification, but it does not work for me. What I see, is changing from, say, homepage to forum page, that is it, this is all history I need. I don't care that I scrolled ten pages, I don't want to hit Back ten + one times to get back. I want to click Back once to get out from forum, and then to click Forward once to get again to the last forum topic I was browsing. This is it! Just show me the current state I left the object in, do not show me all stupid transitions.
And by the way, the implementation of history navigation in Backbase forum is not complete. Say, you selected Forum, General. The top portion of the page shows first page in the list of forum topics. Notice, that "Pages" highlights page "1". While you move to the second, third, etc page, the "Pages" will highlight "2", "3", etc. Now click Back button. The URL in the address line is changing, but the forum topic list is not updated, and "Pages" does not display page number corresponding to a page. So, the implementation of Back button in Backbase forum is incomplete.
The question is: even if you like to record all your actions into history, would you prefer an incomplete implementation, or no implementation at all?
Ajax liberated us from the history list, which is usually a worst enemy of a web application. Please, do not reinstate it back simply because you want to comply to HTTP standard. This standard talks about hyperdocuments, not web applications. HTTP 1.1 is dated back to 1999. Seven years passed already. Remember what happened to Windows from Win3.1 (1991) to Win95. A huge leap. We need a leap in HTTP spec as well. Anyway, as far as I remember, HTTP does not require to record each view change into history, it simply requires the view to be presented in the same way, if it already were in the history list. These are different things, aren't they?
+1 to Michael Jouravlev
Don't forget about "open link in new window" capability - described by Michael way allows to handle it properly either.
What users really need is expected behaviour of browser, not a new puzzle to solve - will back button work or not? can I click 'refresh' button, or will it crash my important database records? Try to guess...
All this AJAX misusing reminds me time when every 2nd page was decorated with a background picture, making text absoulutely unreadable, because everyone learning HTML discovered such a cool feature.
I think it's time to coin new term POWA - Plain Old Web Application which supports all standard back / forward / refresh / bookmark navigations as expected. And you know, not all usages of AJAX break this expectations.
Good points. Even now in 2009 I'm still wresting with this problem. On thing I'd like to point out is that it's important to get a consensus from your team about how the back/forward functionality even SHOULD work in an AJAX app before you start solving this problem in any given app. I'm doing a fairly complicated AJAX navigation to filter a large group of products and then if a user pages through those results and then goes to a detail page, then to another related product detail page from the first detail page and then clicks the AJAX back button we can choose to send them back to the page of AJAX results they were last viewing with a single click instead of making them go through all the previous pages to get back to the results. I found that doing some simple hashing of query arguements and saving them in the session, then comparing those on each request was very useful for creating this type of functionality. If someone submits the same request args multiple times, it only gets added to the history stack once. Of course, once I built this functionality, we ended up deciding we didn't even want it to work that way because it was not the expected behavior for "back" functionality and we found that it was confusing people a bit. Anyway, setting clear requirements for AJAX navigation functionality BEFORE you implement it is essential if you want to keep your sanity intact and your customers happy. But you already knew that right? :)
wait a sec, i thought that was the point of using ajax was to avoid back button problems as an accessory to the current view?
I add an item to my cart, now I see the cart. I use ajax to commit a bunch of different processes within the cart such as sorting, changing quantities and removing items. When i hit the back button, i get to go back to where I added the cart from. tying browser history to all of those cart modifications is exactly what you DON'T want to do.
if you want to track interactions, don't use ajax.
I think with any shift in paradigm of technology it's important to always be flexible in moving away from the current standard. I've always thought Jakob Nielson's thoughts need to applied carefully and when looking at the back button requirement, is it really a good idea?
I find it interesting to watch my 3 yr old navigate web sites. She doesn't use the back button. Most of the sites she visits are well designed enough that she understands how to navigate successfully within the content of the web site. Taking a look at some of the sites she uses, I realized there were navigation methods on the pages that my daughter found, but I did not.
To that end, it makes me wonder if the back button is more of a crutch, and instead of continuing support it, it should be gradually phased out.
Disclosure: I work for Backbase
I think there are two topics:
- how should you use the Back-button in Ajax (if at all)?
- if you want to use the Back-button with Ajax, how do you implement it?
Mark's article on Dev2Dev is about the second question. It illustrates that there are a lot of technical issues to overcome to properly implement Back-button support into Ajax sites. It also shows that the Backbase AJAX framework simplifies this significantly (in a fairly elegant way), and also adds support for the forward-button, bookmarks and page refreshes. As a developer you can decide exactly when you want to push a state change onto the history stack. So I personally think it's pretty complete, and very configurable.
Regarding usabilility: I think you should look at each situation separately, also depending on the target audience. In an RSS reader I like to use the Back-button, together with more desktop-like navigation mechanisms. Indeed, for a very simple content-focused website you might not want to use AJAX. For a desktop-type application that runs in the browser, you probably want to avoid navigating away from the application, because the user would loose the complete application state. So some control of the back-button is useful. Anyhow, too many situations to quickly mention.
To Michael: your solution seems like a very elegant way to control the history stack in a multi-page application, as opposed to a single-page AJAX application, or am I wrong? Regarding the Backbase Discussion Forum: I like it this way, but I guess that's a personal preference. We indeed need to configure the back-button to work with the paged message list (this is easy to do).
I encourage everyone to read the original article, and you also might want to take a look at the discussion over at Ajaxian. And there's also another article on the Backbase implementation (yes, this uses an AJAX bookmark).
To Michael: your solution seems like a very elegant way to control the history stack in a multi-page application, as opposed to a single-page AJAX application, or am I wrong?As I suggested earlier, I would like to differentiate between single-load and single-location. I can build a logically single-page application that will have the same address, but it will reload pages with each request. This is not Ajax, but user experience is the same though usually slower because a whole page is reloaded. I started to use XHR just recently and I was able to combine Ajax and non-Ajax mode in one dual-mode component. I still have to resolve the deep-link issue, though ;-)
JSP Controls: Create page components with JSP