February 17th, 2010
Typically, the user interface in Web Applications is composed of multiple pages. Now with the increasing popularity of AJAX, it is common that people want to develop Web applications that are similar and provide the same user experience as desktop applications. One common problem in Web applications is the constant page reloads and flickering when navigating the application.
Disclaimer: We are writing this documentation as part of the new Web Client Guidance that is being done in patterns & practices. We are close to finishing this project, so I would like to get more feedback or validation from everyone that gets the chance to read this before we release. Have in mind that the content of this topic can change both in content and in form (it can change because of YOUR feedback).
Any of the following conditions suggest using the solution described in this pattern:
- You want to minimize the page reloads and flickering when navigating through the application.
- You want to change only the content of the page and maintain the general layout; that is the header, footer, and menus, when updating the page.
- You want the user to keep the context of most of the page, while only manipulating the data on part of the page.
- You want to have long running processes and/or avoid losing/refreshing dynamic content state while navigating (for example, uploading files or a chat window).
- You want to improve the user experience of Web applications, by simulating the look and feel, and usability of desktop applications.
Have all of your page features, or at least most of them, in a single page. This is known as the Single-Page Interface (SPI) model. In the SPI model, all browser interactions with a Web application occur inside the boundaries of one page.
The SPI pattern improves the UI navigability of Web applications because it decreases the number of page reloads and eliminates flickering.
The SPI model requires a number of highly interactive features, which include in-place editing, context-sensitive user interface, immediate user feedback prompts, and asynchronous operations.
The Single-page Interface pattern elements
SPI is an AJAX pattern that suggests you have only a main page in your Web Application. This page interface is rearranged as a result of user interaction with the application.
Having a single-page interface, may result in your application using less-distinct URLs. Therefore, this pattern may not provide good support for search engines, unless explicit mechanisms for also allowing the navigation of the site by using full redirects are implemented.
The Single-page Interface pattern has the following liabilities:
- As all interactions occur within a page, there are less distinct URLs. Therefore, this pattern does not inherently provide good support for search engines
- You need to implement a mechanism to identify the different states of the application; this is for providing history browsing support and bookmarking. It might be used also for supporting permanent link. Unique URLs and deep linking can be supported in an SPI app but with additional development cost. Web applications built using more traditional full page refreshes support unique URLs and deep linking more easily.
- You have to be careful with memory leaks, because as the page is not refreshed as often, the memory is not cleaned automatically by the browser. Therefore you have to manually dispose objects, handlers, and so on, when navigating through the page.
Identifying the State of an Application with Distinct URLs
When using AJAX and the SPI pattern, an application may perform different operations, and therefore pass through different states while the URL in the browser stays constant. This creates the need of a mechanism to identify different states of the application, for example, for moving back to a previous state.
Browsers implement the Back and Forward buttons functionality by caching the list of visited URLs.
In AJAX, the server communication is done through XMLHttpRequests, and these requests do not change the page URL. Therefore, the list of visited URLs is not modified.
The Unique URLs pattern helps addressing this problem, by assigning a unique and expressive URL to each significant application state.
Scripting does not provide a mechanism to modify the list of visited URLs, but it provides mechanisms to modify the URLs.
Note: Setting the hash property does not work reliably on all browsers, and you do not get change notifications on all browsers either. For this reason, it is recommended using some library that handles these differences in a cross-browser way, such as the Microsoft Ajax Library History control.
Therefore, when there is an important state change in your application, modify the URL hash property. In this way the changes will be tracked by the browser.
window.location.hash = stateData;
The resulting URL will look like the following.
Once you have identified each relevant state of the application, you need to implement code to parse the URL. You can choose the format based on your specific needs to represent a state, you can even add parameters in the URL, as seen in the following example.
Finally, after parsing the URL, you should restore the application to the corresponding state based on the hash data, keep in mind that the hash data is not sent to the server as part of the URL. In the previous example, when loading that URL, the application should go to the product details form, showing the details of the product with ID 5529.
For more information about the Single-Page Interface pattern, see the following:
- Single-Page Interface and AJAX patterns on MSDN Magazine
For more information about software design patterns applied in the Web Client Guidance, see Patterns in the Web Client Guidance.
You can find this and many other topics and key decisions for creating web client applications (both in ASP.NET Web Forms and ASP.NET MVC) in our latest Web Client Guidance drops. We are close to finishing this guidance, so your prompt feedback is invaluable to us. Make sure you check it out and comment in this topic or in the codeplex forums (there is a special tag to mark conversations for this new guidance).