Suppose that you have thought out the design of your Web application. Your draft Web pages are neat and succinct. You filtered out all those large images and other unnecessary stuff. You strove to write less text...so the download time of your pages is acceptable for visitors with both high bandwidth and dial-up connections. But you're probably still concerned with some specific usability issues because your visitors are waiting patiently for the information they need as the page is loading. Well, you're on the right track and ready to consider another usability improvement -- how your page is loading as well as how promptly it loads. This article gives you a detailed technical exploration of how you can improve the page loading process.
According to Jakob Nielsen's "The Need for Speed" column on Web usability (see Resources), one of the most important goals of Web site design is to minimize response times:
- The overriding design criterion must be speed.
- The most important issue for response time is how soon the user sees useful information on the screen.
- The size of the full page is less important if the user can quickly start acting on some information.
This article focuses on the third clause. Every Web page has its own particular, most valuable information. Your goal is to allow the browser to display the appropriate valuable information even though only a small chunk of the page content is loaded. To achieve this goal, take the following points into account:
- Successive transmission of the DHTML code enables the browser to render the page during loading
- Browsers can cache previously received data
- Modern browsers are capable of greatly speeding the response time by partially reloading the page
Creating user-friendly HTML tables
Since the table tag allows coders to organize content in a Web page flexibly and efficiently, the page content is often enclosed within a <table> </table> pair. During loading, the browser can start rendering the table only if the entire table is loaded or if the entire table row is loaded. If we want to show the just-loaded chunks of the data continuously, this causes an inconvenient constraint on using tables . Ideally, you should meet the following constraints:
- Avoid nesting tables, if possible
- Keep tables short
- Avoid using tables to lay out elements on the page, if possible
To fulfill these requirements, you can exploit several coding techniques. To illustrate them, I will use a sample Web page with a typical layout. Figure 1 shows the sample page, consisting of 5 different areas. Such pages are often coded as a single HTML table with considerable nesting. This style of coding can significantly extend the delay that visitors experience when loading pages: they see a blank screen until the whole page is loaded.
Figure 1: Standard Web page layout

You can split the page layout into multiple independent tables, preserving the browsers' ability to render each of them step-by-step.
As many Web developers do, you can implement the upper area (header), the center area (left column, main content, and right column) and the bottom (footer) of the page as three independent tables (see Listing 1). In this case, the header will be rendered when the central area is loading. The visitor still has to wait for the valuable information (the main content) to download before it is loaded entirely.
<body> <table cellspacing=0 cellpadding=0 border=0 width=100% height=33> <tr><td bgcolor=#dddddd>[1] Header</td></tr> </table> <table cellspacing=0 cellpadding=0 border=0 width=100% height=160> <tr> <td width=22% bgcolor=#f3f3f3>[2] Left Column</td> <td width=56% align=center>[3] Main Content</td> <td width=22% bgcolor=#f3f3f3>[4] Right Column</td> </tr></table> <table cellspacing=0 cellpadding=0 border=0 width=100% height=33> <tr><td bgcolor=#dddddd>[5] Footer</td></tr> </table> </body> |
With a little more code editing, you can split the table for the central area into three horizontally stacked tables.
To display two or more columns of the page layout as independent tables, some of the tables should occur as a floating objects. An example of the default floating object is the image tag. The image element floats on the left side of the Web page text, since its align attribute is implicitly set to left. The align attribute of the table tag determines whether the table floats, causing another floating objects and the surrounding text to flow around it.
Thus, all the columns can be implemented as the corresponding floating tables. For the last occurring column, you can choose between two options: Allow it to be a floating table (as shown in Listing 2) or regular HTML code, that flows around the floating objects (see Listing 3).
<!-- header goes here --> <table align=left cellspacing=0 cellpadding=0 border=0 width=22% height=160> <tr><td bgcolor=#f3f3f3> [2] Left Column </td></tr></table> <table align=left cellspacing=0 cellpadding=0 border=0 width=56% height=160> <tr><td align=center> [3] Main Content </td></tr></table> <table align=left cellspacing=0 cellpadding=0 border=0 width=22% height=160> <tr><td bgcolor=#f3f3f3> [4] Right Column </td></tr></table> <br clear=all> <!-- footer goes here --> |
<!-- header goes here --> <table align=left cellspacing=0 cellpadding=0 border=0 width=22% height=160> <tr><td bgcolor=#f3f3f3> [2] Left Column </td></tr></table> <table align=right cellspacing=0 cellpadding=0 border=0 width=22% height=160> <tr><td bgcolor=#f3f3f3> [4] Right Column </td></tr></table> [3] Main Content <br clear=all> <!-- footer goes here --> |
Listing 2 and Listing 3 display the main content column quite differently.
In Listing 2, browsers treat the left, main content, and right columns as ordinary HTML tables.
In Listing 3, browsers position the main content column regardless of the layout of the surrounding columns. The main content following the left and right columns is placed between the floating tables. When the main content column has more content than can fit within the height of the floating columns beside it, the text of the main content flows below the end of the columns. In other words, browsers will use the entire width of the page to display the main content column. This may be a pleasant feature particuarly if the height of the main content column significantly exceeds the height of the columns next to it.
The most important feature of the second approach is: since the main content column is separate HTML code, you have the option to not enclose it in the <table> tag. Then, browsers can render the column immediately as the page is loading.
Moreover, you can change the sequence of columns loading. If you want to, you can rearrange the appropriate tables and handle their align attribute as illustrated in Listings 2 and 3. Listing 2 arranges to load the page areas in a straightforward way; the code in Listing 3 claims to deliver main content column after delivering the left and right ones.
Constraints for floating objects
While working with floating tables, keep the following issues in mind:
- The floating tables layout technique is less flexible than the plain table layout technique. In particular, floating objects lack the powerful layout features of table cells, which are so appreciated by Web designers.
- Netscape Navigator 4.x starts rendering floating objects only after the entire group of tied floating objects is loaded. Thus, the users of Navigator 4.x receive very little benefit when the floating tables technique is used in any Web page.
- Netscape 4.7x has a bug that occurs when you use the percentage width of multiple floating objects. This version of Netscape incorrectly diminishes the width of each subsequent tied floating table.
You can further improve the loading speed of Web pages by using the table-layout CSS attribute. Internet Explorer 5.0 and Netscape Navigator 6.0 introduced the fixed table layout feature. If you modify the table to use fixed-table layout, the browser displays table rows instantly while the table loads. And so, you can improve each column in the sample page. Of course, it makes sense only if the column is long enough and if the column takes quite a while to load. See Resources for an article that details how to use the fixed-table layout style.
Note that Internet Explorer does not render each row of the table independently, even if the fixed-table layout attribute is set. Instead, it incrementally renders chunks of the table; each chunk contains about 10 rows. Unfortunately, if you have less than 10 rows in your table, Internet Explorer displays them only after delivering the whole table. I've tried versions 5.0, 5.5, and 6.0 of the Internet Explorer browser, and all of them share the same lack.
Creating client-side scripts and page loading
By using the external scripts feature, the client only has to download the .js file once. Usually, client-side developers use external scripts this way:
<html><head> <script language=javascript src=common.js></script> </head> <body> <form onsubmit="return validateForm()"> <!-- form elements --> </form> </body></html> |
But, consider another way -- why not reference the external script at the end of the HTML code? If you do so, the visitor will be able to load the visible part of the page faster, and only afterwards the script will be loaded. In this case, the size of the script becomes less crucial for the visitor. If you want to let users interact with the page elements while the page is loading, this approach may be not applicable. And if you use inline scripts such as onsubmit="return validateForm()", remember to check the availability of the objects used in the external script before invoking them.
Another idea is to use external scripts to cache common HTML code such as headers and footers. You can write this common information in the browser window using the document.write() method. If you use this approach, take the following into account:
- Users can disable Javascript for Netscape Navigator but not for Internet Explorer
- Intensive mixing of static content and dynamically generated HTML code may slightly degrade the page rendering performance
Testing page loading time with low bandwidth emulation
When you test your Web site, you should browse at typical modem-speeds.
If you are running an Apache Web server, there is a tool to serve your needs: the mod_bandwidth Apache module. This module enables the setting of connection bandwidth limits, and thus can be used to emulate low bandwidth connections. Browsers download the main HTML page, related images and other data asynchronously. You should reduce the total transfer rate to accurately emulate dial-up connections, instead of specifying the same unchangeable low transfer rate for each download. The mod_bandwidth module allows you to emulate dial-up modem connections accurately.
- Review "The Need for Speed" by usability expert Jakob Nielsen. This March 1, 1997 article is still vital reading today.
- Explore issues related to Web page performance in "Building High Performance HTML Pages."
- Read Tong Li's recent article "Exchanging information with a server without reloading your HTML page" for three techniques that can greatly improve Web page performance. (developerWorks, January 2002)
- Check out Enhancing Table Presentation to learn how to increase table rendering speeds with the fixed-table layout style.
- Try the CSS Positioning, Part II tutorial to see how to lay out Web pages without using any tables at all.
- Get the Extreme HTML Optimization tips on improving HTML coding.
- Use the mod_bandwidth Apache module to emulate low connection speeds.
Eugene Logvinov is a lead developer for DataGrapes, a development group centered around Web application development. He is currently working in the area of Web-based user interface design. You can contact Eugene at rezonal@univer.kharkov.ua.
Comments (Undergoing maintenance)





