Multi-Stage Download - Ajax Patterns

Multi-Stage Download

From Ajax Patterns

Evidence: 1/3

Tags: Multi-Stage Incremental Download


Contents

In A Blink

TODO Diagram: Diagram showing full website, labels indicate time of download.


Goal Story

Stuart visits a fashion website in order to locate a new brand of sunglasses he has just discovered. He reaches the content quickly because the navigation-related information on each page loads independently, so he can click through without having to wait for the entire page to load.


Problem

How can you optimise downloading performance?


Forces

  • Content can be time-consuming to load, especially when it contains rich images.
  • Users rarely need to read all the content on the page.
  • Users often have to click through several times to locate a particular item.
  • Users sometimes browse around by exploring links between pages.


Solution

Break content download into multiple stages, so that faster and more important content will arrive first..

There are often times when an application needs to download a lot of content from the server. In particular, on startup and when a major context switch occurs. If you request it all in a single XMLHttpRequest Call, the response won't be complete until everything's been processed. Thus, you open up the risk of bottlenecks, where a single piece of content blocks everything else from returning.

The solution here suggests using multiple XMLHttpRequest Calls. The same amount of information will be returned from the server, but it will be processed and transmitted in paralllel. Typically, the page is divided into placeholders (e.g. div elements) with the content for each placeholder downloaded independently. In general, the calls can all be issued simultaneously, and the page will gradually be populated as the calls return.

You could use this pattern to load a page initially. One download might be very small, containing just a skeleton of the page with content geared around navigation - links to other pages, and enough information about the current page for the user to decide if it's worth sticking around. That's the critical content for a fresh visitor, and there's no need to make them wait for the rest of the page to load. The browser can request the main page content as a separate call.

Multi-Stage Download is especially useful for conventional websites, rather than Ajaxian applications, because an Ajaxian application should only have one page load. Still, there may be times when even an Ajaxian application undergoes a significant change, especially if there is a lot of functionality on offer.

This pattern is in some respects an Ajaxian upgrade of conventional guidelines for optimising the page load. A couple of pertinent techniques:

  • Preload images which will be used later
  • For pages which result from complex processing, begin by outputting part of the page, and only then perform the processing to complete the page.
  • Use frames to fix navigation links. (However, frames have so many problems that this guidelines is rarely worth the trade-off.)

One resource risk is having too many requests at once. Thus, consider a "Multiplex Call" variant: Establish a browser-server protocol that lets the browser wrap multiple requests and the server wrap multiple responses. Then, only issue a single call with all required data inside. The immediate response might only return a few results, so the browser waits a bit, then makes a further request for outstanding data. The whole process repeats until the browser has all data.


Decisions

How will the page be divided into blocks?

The trickiest decision is how to divide the page into blocks, each of which will be downloaded individually. Since the blocks are downloaded in parallel, the main advice is to create small blocks of initial content to ensure the initial download is quick, and to group together content that's likely to be ready at the same time. Also, too many blocks will give the initial load an ugly appearance, and may have the undesirable effect of causing already-displayed elements to move around. For a fresh visitor, one example would be to create blocks as follows:

  • A block of general information about the website, e.g. name, summary, a small icon.
  • A navigation block showing links within the site.
  • A block of general information about the current page, such as a heading and summary text. In a web application, this may be dynamic information based on what processing is being performed.
  • One or more blocks of main page content.
  • One or more blocks of auxiliary information, e.g. cross-site promotions, advertising, legal notices.

Some of these may well be combined too, as it's important to avoid too many blocks. So you might have a single request to retrieve both navigation and general information, which is then split and painted onto separate blocks.

Note that this doesn't have to apply to a homepage - if you are offering Unique URLs, visitors can jump into an Ajaxian application at different points, so the main page content might actually be quite "deep" into the application.

How will the page be structured?

Ideally, this pattern should not affect the page appearance, but will require some thinking about the underlying HTML. In particular:

  • As new information loads, it's possible the browser application will automatically rearrange the page in order to accommodate new information. This can lead to the user clicking on the wrong thing, or typing into the wrong area, as items suddenly jump around the page. Ideally, information will not move around once it has been presented to the page. At least for images, it's worthwhile defining the width and height in advance, as CSS properties.
  • CSS-based layout is likely to play a big part in any solution, as it provides the ability to exercise control over layout without knowing exact details.

What format of content will be downloaded?

HTML Responses are the most obvious format to pull down, so that it can be directly set using the innerHTML attribute. Semantic Responses can also be used quite effectively, with the browser morphing content as the responses arrive.

What happens to the blocks while their content is being downloaded?

The entire DOM itself can be established on the initial load, so that DIVs and other structures are used as placeholders for incoming content. If that's the case, most of those elements can be left alone, but if the user is waiting for something specific, and it may take some time, it would be worth placing a Progress Indicator on the block where the output will eventually appear.

It's also possible to construct the DOM dynamically, so that new elements are added as new content arrives. This approach may be more work, but may help to decouple the browser and the server. With the right framework in place, it means that the browser does not have to know exactly which items will be downloaded. The browser might ask the server to send all adverts, and the sender simply responds by sending down an XML file with three separate entries, which the browser then renders by adding three new divs.

Will the calls be issued simultaneously?

Let's say you're at a point where you suddenly need a whole lot of content. Should you issue several requests at once? Not necessarily. Keep in mind there are limits on how many outgoing requests the browser can handle at one time and consider what's best for the user. If there's a bunch of content that might not be used, consider deferring it for a bit with a Javascript setTimeout call. That way, you can help ensure the user's bandwidth is dedicated to pulling down the important stuff first.


Real-World Examples

Kayak

Kayak is a travel search engine. You tell it where you're going, and it then searches through many online travel sites to build up a set of options for you.

After entering a search query, the results page initially shows just the site banner, the search you entered, and a Progress Indicator. As the results for each external site arrives, Kayak adds the site name and whatever flights it found there. The flights aren't just appended, but kept in sorted order. You also have the option to finish the search by clicking an Enough Results button.

PressDisplay

Press Display uses Ajax to show full-colour scanned nespapers from around the world. When you click on a country, the page changes to shows each available newspaper. The newspapers are loaded into pre-defined placeholders. Then, when you open up a newspaper, a few things happen in parallel:

  • A placeholder is created for the main page content, and the image downloaded.
  • Placeholders are created for the page thumbnails, and each thumbnail downloaded.
  • A set of navigation controls is added.

TalkDigger

TalkDigger is an Ajaxian meta-search for web feeds. Tradtional meta-searches usually output results to the browser as they're received from individual engines, so the results page isn't well-ordered. With TalkDigger, each individual search engine gets its own div on the page. As the results come in, they're placed on the right spot.


Code Example

The code example is a portal demo which downloads content in various stages:

  • The page banner and key links are downloaded immediately, as part of the initial HTML.
  • On page load, a place is set aside for side links, which are then requested and injected into the placeholder.
  • Likewise, the main content is also requested on page load.
  • Finally, an ad is requested after a short delay. This ensures the main content arrives first, so the ad doesn't affeect the overall flow. (If you're feeling entrepeneurial, you might prefer to reverse the order.)

The initial HTML contains the header and placeholders for the content which will be injected. There's an initial "Loading" message for each of these.

    <h1>ajax patterns Portal demo</h1>
   
    <a href="http://ajaxpatterns.org">Ajax Patterns Wiki</a> |
    <a href="http://ajaxify.com">Ajax Demos</a> |
    <a href="http://ajaxpatterns.org/Ajax_Examples">Ajax Examples</a>
   
    <div class="spacer"> </div>
   
    <div id="leftLinks">
      <div id="siteLinks">Loading ...</div>
      <div class="spacer"> </div>
      <div id="ad">Loading ...</div>
    </div>
    <div id="allPatterns">Loading ...</div>
  

The side links and main content are loaded immediately on page loaded, and sent to a callback function which morphs the corresponding div:

 window.onload = function() {
   ajaxCaller.get("sideLinks.html", null,
                  onServerResponse, false, "siteLinks");
   ajaxCaller.get("allPatterns.phtml", null,
                  onServerResponse, false, "allPatterns");
   ...
 }

 function onServerResponse(html, headers, elementId) {
   $(elementId).innerHTML = html;
 }

A few seconds later - probably after all the content has been loaded - the ad content is requested:

 window.onload = function() {
   ajaxCaller.get("sideLinks.html", null,
                  onServerResponse, false, "siteLinks");
   ajaxCaller.get("allPatterns.phtml", null,
                  onServerResponse, false, "allPatterns");
   *** setTimeout("ajaxCaller.get('ad.html',null,onServerResponse,false,'ad')",
              5000); ***
 }


Alternatives

All-In-One

As was mentioned, the alternative - and the de facto choice - is to download everything in one go.


Related Patterns

Portlet

Portlets are good candidates for content-specific downloads. A portal's overall structure can be downloaded initially, and each portlet's content then be downloaded (and refreshed) in parallel to the rest of the page.

Guesstimate

While a block is waiting to be loaded, you might populate it temporarily with a Guesstimate.

Progress Indicator

While a block is waiting to be loaded, you might populate it temporarily with a Progress Indicator.

On-Demand Javascript

Like Multi-Stage Download, On-Demand Javascript suggests an initial download followed by further downloads later on. That pattern focuses specifically on Javascript content rather than display and semantic content. It's also about downloading only when needed. The emphasis here is on downloading according to an initial schedule. Other patterns, such as Microlink and Live Search, cover on-demand downloading of display and semantic content.


Visual Metaphor

Multi-Stage Download mirrors agile project management. If you can deliver some really useful things early on, why hold off until everything else is ready?