What about repetitive HTML sections?
AJAX verbalized that the Emperor was naked.


  AJAX In Action: Making The Fastest Photo Album



I
N
T
R
O

his article shows how to start the creation of a complex photo album site that requests minimal downloads from the server. Instead of loading several pages, requested updates take place on the client-side via dynamic changes of a single page. At the end of the series the reader will have a fully functional, cross-browser, fast and compact photo album application that does not even need a web server.

  Historical Review

AJAX is not really a new technology. It revisits accepted principles and approaches, combines others, and puts good old technical tricks in one paradigm. When we review the web sites created by regular development tools, we must admit that their architecture is far from optimum regarding response speed. AJAX helps us create faster sites by eliminating some downloads and round trips to the server. But be aware. AJAX, as many other successful ideas, has already been abused by some companies. Fortunately, a new buzzword is here to abuse, and these companies tend to ride the "Web 2.0" wave lately.

If you create "AJAX enabled" applications with .NET or other script-writing software, you may end up having as slow and bloated code as other, non-AJAX pages created with these IDE-s. Don't forget that the letter J in AJAX stands for Javascript and not Java, C or VB.Net that generate Javascript. Again: If you want compact and fast code, don't rely on code generating software. Start your development from scratch.

Since the industry got obsessed with drag-and-drop, point-and-click development, the quality of the resulting code has became marginal. Microsoft's FrontPage or Visual Studio, Macromedia's Dreamweaver or ColdFusion are good products in a sense that non-technical people can develop good-looking web sites with them. If someone can edit a document in Word, she can make an HTML by clicking on the “Save as a web page”. What is common in the web pages created with the above WYSIWYG tools, or with many other, so-called RAD tools? They all are lengthy and redundant. They don’t consider limited band width, readability or optimization for the speed of displaying pages. People don’t have fast enough connections for these long pages? Have the visitors buy a faster modem, subscribe a faster Internet provider and have the web site owner move to a faster web server. Since the existence of CSS it is obvious: there is no place for repetitive styling in the HTML lines. But what about repetitive HTML sections?

Developmental methods that don't use dynamic HTML have a serious problem. They create and send repetitive HTML over and over again. The server-side script itself is not necessarily redundant but the resulting pages are. A script that creates three rows and four columns of complex cells generates a table of twelve cells. The internal structure of the twelve cells is spelled out twelve times in the transferred HTML, although only one relatively small difference may occur among the individual cells. One may argue that repetitive HTML is necessary because one cannot create a loop in HTML. It is true but it does not keep us from running a loop on the client-side that creates an HTML of repetitive structure. Instead of a multi-second download, we can run a client-side script in milliseconds.

AJAX verbalized that the Emperor was naked. Or better to say, he was overdressed. Why should we retransfer the same page or the same page elements with minor differences multiple times? Take a typical application, an online photo album as an example. When the user wants to see the next picture of the album, we do not need to send any HTML from the server at all because we have the structure and most of the content on the client's machine already. All we need to request and send from the server is the new picture.

There are dozens of applications that create photo albums. They all compete in appearance but don’t care much about the optimization of network traffic. A typical developer tool gives a set of choices in colors and shapes. The better ones collect the user’s choices and produce a CSS file according to the chosen “skin”. Then they create as many alike static HTML pages as many photos are included. Clicking the Next or Previous button results not just in the loading of a new picture but the loading of a similar HTML page, with two differences. The obvious one is that the source attribute of the IMG tag has been changed to the name or URL of the new picture file. The second difference is that the new state of the site has also been stored somewhere. Either on the server or on the client-side, for example in a cookie, in a hidden inpuut box, in a database, or in a search string of the URL.

What is the cost of resending pages and structures with minor differences? One of the best photo album creator software is Jalbum. It offers beautiful skins, fast and automatic creation of slides and thumbnail pictures. However, the resulting site contains as many similar, 10k HTML pages as many pictures the album has. An album of only 10 pictures contains 100k repetitive HTML.

In the following articles I will show a complete photo album application that uses less HTML, a bit more client-side scripts but no server-side scripting at all. It contains one single HTML file of about 10k. When we double the number of pictures, Jalbum almost doubles the size of its index.html and it doubles the number of its 10k HTML pages. Even worse, at every mouse click one of these 10k files will be downloaded. The size of my photo album, called Been There Done That or BTDT, is independent of the number of pictures, and it does not request a new HTML page at each click.

One AJAX school suggests that the site should store its state on the client-side in a hidden frame or in a hidden iframe. It also suggests that reusable information, like the list of file names of the pictures should also be stored there. In this case, the download of a new page does not necessary occur before an image or text content changes. In my solution clicking the Next or the Previous button would invoke the dynamic change of the image source of the same page. This way the client requests a download of another image only, if the image is not in the client machine's cache already. Not even a click on the thumbnail view invokes a new HTML load. Do you have five or fifty albums? The same small HTML page can display all of them.

Here are the snippets completing the above tasks:

  1. The IMG tag in the HTML file:

    <img id="Img0" class="image" src="url or file name
    of the opening picture" alt="picture" />
  2. The JavaScript codes that handle the dynamic change of the picture:

    a) The declaration of an onclick event function of the buttons:

    objButton.onclick=function() {setImage(albumNo, picNo)};

    b) The setImage function:

    function setImage(albumNo, picNo, imgId){//Sets image source
       if (isNull(imgId))   imgId = "Img0";
       if (isNull(picNo))   picNo = 1
       if (isNull(albumNo)) albumNo = 1
       var oImg0 = getObj(imgId);
       oImg0.src="images/"+arrNames[albumNo][0]+"/" +
               arrNames[albumNo][picNo];
    //… Maintain state here …
       return true
    }

The first three lines implement a simple polymorphism. They ensure that setImage can be called with zero to three arguments. For example, setImage( ) without an argument can display the default picture, say, when the visitor clicks the Home link. In this case no page reload should occur as opposed to 99.9% of similar web sites.

setImage calls two simple, general-purpose, cross-browser functions that speak for themselves:

function isNull(obj) {//Check undefined explicitly (NS6.x)
  return(obj==null)||(obj==undefined)
}

function getObj(id, doc) {//doc can be an XML document object
 if (isNull(doc)) doc = document;
 with (doc) {
  if(!isNull(getElementById(id))) return getElementById(id);
  if(!isNull(getElementsByName(id)))
                              return getElementsByName(id);
  if(!isNull(getElementsByTagName(id)))
                              return getElementsByTagName(id)
  else return false
 }
}

The second function is also polymorph in the above sense. With one argument, it returns an object of the window document. Giving an XML document as the second argument will be handy when we retrieve the directory names and file names from an XML file. BTDT handles multiple albums. After I read the XML file of all album names and picture names, I store them in a two-dimensional array arrNames[ ][ ]. If you are not familiar with XML, you may avoid reading the data from XML. Just hard-code this array the following way: The 0-th element of the array representing the i-th album is the name of subdirectory in which the pictures of the particular album reside:

  arrNames[i][0] = “name of subdirectory containing album i”
  arrNames[i][j] = “name of picture j in album i”(j>0)

With the above design a single page load will handle the functionality of browsing through several albums in single view and in multiple-picture thumbnail view. This architecture also allows us to play a slide show without loading new pages, by timing and imitating clicks on the Next button periodically.

You can check out my photo albums at scriptwell.net/myPhotos. Recently I messed up the non-IE part of the XML load, so, temporarily it works only in IE 6 or 7. It is not as nice (yet) as those generated by Jalbum but definitely faster and more compact.

Here is the first version of BTDT. It contains the list of albums and pictures burned in, i.e., hard-coded in the arrNames[i][j] array.

The next article, Fixing The Broken Bookmark solves a common problem of partial change of page contents. Then I'll show you how the XML data read and the slide show are implemented and how the thumbnail view can be handled without loading a new page. Another article is about speeding up the Photo Album Application by proper preload technique.

You can find the complete HTML, Javascript and CSS code lists of the Photo Album Application in the last article of this series.

  Questions

  1. The usual way to visit a site is to go to the opening page or home page first. So, before the visitor clicks the Home link somewhere in your site, the opening page has already been visited. Does your web site reuses the previously downloaded opening page in this case or does it request a reload from the server?
  2. Have you created or have you used a photo album creator? Does it change the displayed photo by dynamic change of the IMG tag's source on the client side or by loading another HTML page or a page generated on the server side?