Speed up your Web pages

Twenty (plus) tips that make all the difference

Do you want faster-loading Web pages? Learn how you can make the browsing experience better for dial-up users by reducing loading times by as much as 80 percent, in some cases.


Marco Kotrotsos, Founder and developer, Incredicorp

author photoMarco Kotrotsos is a developer with 10 years of experience building software systems ranging from enterprise-class applications for top insurance companies to administrative tools for SMBs and Web applications for startups. Marco is the founder of Incredicorp, which focuses on helping startups and small businesses get their product to market. He collaborates with technical experts on leading-edge topics such as semantic Web, AI, CSS3, and semantic search.

27 January 2009

Also available in Chinese Japanese


Not everyone is blessed with a high-speed Internet connection. Even if everyone were, there can be hundreds of reasons why your Web application seems slow and sluggish. In this age of ever-increasing broadband speed, don't think that you shouldn't pay attention to page load times. Shave off valuable seconds of your page load times and even more valuable milliseconds of your request and response times. You'll create a better experience for your visitors.

After reading this article, you will have a better understanding of the basics of Web page load time optimization. You'll also have the tools and knowledge to better identify and judge slow-loading page segments and bottlenecks.


Ideally, you should have Mozilla Firefox installed. You should also have an understanding of Web development in general. The topics involved in this article are not difficult, but they'll "click" faster if you know about topics such as Hypertext Markup Language (HTML), Cascading Style Sheet (CSS), and the JavaScript™ programming language. You do not need an integrated development environment (IDE): You can just follow along with your favorite editor.

You must have JavaScript enabled in your browser. Also, to follow along with the segments on Firebug and YSlow, you need the Firefox Web browser installed.

So, you don't have broadband

Many people access the Internet through some kind of broadband connection—be it DSL, cable, fiber-optic, or some other method. However, those users who don't have access to such technologies are forced to use dial-up connections. You've undoubtedly forgotten the dial-up experience, but try to remember back when you actually could see a Web page load line . . . by . . . line . . . .

The 2006 Organization for Economic Cooperation and Development (OECD) report defines broadband as only download data rates greater than 256 kbit/s. The U.S. Federal Communications Commission (FCC) currently defines broadband as anything above 768 kbit/s.

Fortunately, help is on the way for these poor folks. You can improve their experience by decreasing the time required for pages to load. But, users on dial-up are not the only reason to cut back on load and response times. Many Web designers have erroneously assumed that the advent of high-speed Internet connections would make Web site performance optimization irrelevant. This can't be further from the truth. For instance, many tasks that used to be performed using desktop software can now be done online. Getting the same responsive feel in a Web application as you have in desktop software can be quite difficult, and performance optimization is incredibly important. Luckily, several tools and best practices are available to decrease response and load times for a much snappier experience.

According to Birds-Eye's Broadband Statistics for 2007, 25 percent of people in the United States have no Internet, 53 percent have broadband, and 21 percent still use dial-up.

Tools and essentials

With all optimization-oriented tasks, you must have tools to diagnose bottlenecks and identify problems. Two of the most widely used tools in Web development today are Firebug and YSlow—both Firefox plug-ins that are open source and available at no cost.


Firebug (see Resources) is one of the most popular of the Firefox extensions and an application that makes Web developers' lives much easier. It includes a lot of very useful features, such as:

  • JavaScript debugging
  • The JavaScript command line
  • Monitoring JavaScript performance and tracking XmlHttpRequests
  • Logging to the Firebug console
  • Tracing
  • Inspect HTML elements and live editing of HTML code
  • Live editing of CSS documents


YSlow (see Resources) analyzes Web pages and tells you why they're slow based on the rules for high-performance Web sites drafted by Yahoo! (see Resources). YSlow is a Firefox add-on integrated with Firebug, so you need to have Firebug installed before you can install and start using YSlow.

Install Firebug

Both Firefox extensions are easy to install. To install Firebug, perform the following steps:

  1. Open Firefox, and go to the Firebug home page.
  2. Install the current version of Firebug.
  3. If Firefox is configured to block pop-ups, click Allow to allow the installation window to open. Otherwise, click Install Now.
  4. Restart Firefox.

You can now access Firebug from the Tools menu. You can open Firebug in a new window or in the existing window (see Figure 1).

Figure 1. Firebug's HTML and Style views of the Firefox start page
Firebug views

Install YSlow

After you have installed Firebug, the next step is to install YSlow. To do so, perform the following steps:

  1. Open Firefox, then go to the YSlow home page.
  2. Install the add-on, then restart Firefox.

    Note: Unlike many other Firefox extensions, YSlow does not start automatically. It must be activated first.

  3. To activate YSlow, right-click its icon in the status bar, then click Autorun.

Figure 2 shows the results of the YSlow performance analysis.

Figure 2. YSlow performance analysis of the Firefox start page
YSlow performance analysis

Common sense: Remembering design rules

It is surprising how often simple design rules are neglected, resulting in non-optimized, slow-to-download pages. Bear the following rules in mind, and your pages will load more quickly.

Use good structure

Extensible HTML (XHTML) has many advantages, but its disadvantages are equally notable. XHTML might make your pages more standards-compliant, but its verbose use of tags (the mandatory <start> and <end> tags) means more code for the browser to download. So, all things being equal, try to use less XHTML coding in your pages to decrease page size.

If you really can't go without XHTML, try to optimize it as much as possible. For instance, remove white space and adopt strict XHTML coding practices for faster downloads and parsing. To enforce XHTML Strict, add the following doctype statement to your document:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"      

XHTML 1.0 Strict is the equivalent of Strict HTML 4.01 and includes elements and attributes that have not been marked as deprecated in the HTML 4.01 specification. Remember that a couple of tags that were allowed in XHTML Transitional are not allowed in XHTML Strict, for instance:

  • <center>
  • <font>
  • <iframe>
  • <strike>
  • <u>

Don't overload the layout

Before blogs (and news sites in general) became popular, it was considered bad practice to have pages that scroll horizontally or even vertically. The page size was small, and it was more difficult (although certainly not impossible) to fill up the screen nicely. Now, with blogs and content-driven Web sites, it is not uncommon to see long pages many hundreds of kilobytes in size. Yes, you have more space to fill, but this doesn't mean that you must fill it with large background images, tons of tables, or simply lots of content. Be minimalistic: Less is more. Cluttering your pages with all kinds of images, videos, ads, and so on is a usability nightmare, as well, so think twice before you visually oversaturate the page.

Don't use images to represent text

Unlike fonts, where you have little control over the way they appear in different browsers, images always appear exactly how you designed them. But this isn't an excuse to use images in place of text.

One of the most frequent examples of using images to represent text is in navigation. Fancy buttons may look appealing, but they load slowly. Additionally, images are still not indexed directly by search engines, so using images for navigation is a search engine optimization (SEO) sin. There's no reason to use images of text to represent text when there are many CSS tricks for creating good-looking buttons without images.

One particular type of navigation well suited to CSS styling is tab-style navigation, shown in Figure 3.

Figure 3. Tab-style navigation
Tab-style navigation

Besides being "low cal," this way of implementing navigation is also more Web-standards based.

A Web site that complies with a group of best practices known collectively as Web standards is lean, accessible, search-engine friendly, usable, and CSS based.

The code in Listing 1 and Listing 2 implements tab-based navigation as pure CSS/XHTML.

Listing 1. CSS document for tab-based navigation
    #nav {
      border-bottom:1px solid #54545C;
    #nav ul {
	padding:10px 10px 0 50px;
    #nav li {
    #nav a {
      background:url("tableftK.gif") no-repeat left top;
      padding:0 0 0 4px;
    #nav a span {
      background:url("tabrightK.gif") no-repeat right top;
      padding:5px 15px 4px 6px;
    /* Commented Backslash Hack hides rule from IE5-Mac \*/
    #nav a span {float:none;}
    /* End IE5-Mac hack */
    #nav a:hover span {
	  background-position:100% -42px;
    #nav a:hover {
      background-position:0% -42px;
    #nav a:hover span {
      background-position:100% -42px;
Listing 2. HTML code for tab-based navigation
<div id="nav">
    <li><a href="#" title="Link 1"><span>Link 1</span></a></li>
    <li><a href="#" title="Link 2"><span>Link 2</span></a></li>
    <li><a href="#" title="Link 3"><span>Link 3</span></a></li>
    <li><a href="#" title="Longer Link Text"><span>Longer Link Text</span></a></li>
    <li><a href="#" title="Link 5"><span>Link 5</span></a></li>

Cookies might be small files, but browsers still need to download them. Large cookies take longer to download, which in turn increases the time the browser takes to load the page. That's why it's important to keep cookies as small as possible to minimize the impact on browser response times.

Additionally, setting an earlier expire date, or not setting an expire date at all decreases the response time. To set the expire date for a cookie in the PHP language, use this code:

 $expire = 2592000 + time(); 
 // Add 30 day’s to the current time 
 setcookie(userid, “123rrw3”, $expire);

This snippet sets the cookie called userid as well as the expire date to be 30 days from the current date.

Don't include JavaScript code you don't need, and externalize whenever possible

Similar to cookies, JavaScript files take time to download, which inevitably slows down the whole page. So, use JavaScript files wisely—only when it's really necessary—and optimize your scripts for size and speed.

Another way to speed up JavaScript download times is to use external files instead of including the script inline. This approach is applicable to CSS, as well, because externalized files get cached by the browser, whereas CSS or JavaScript that is coded inline (in the HTML page itself) gets loaded every time along with the HTML. To externalize your CSS and JavaScript code loading by referencing them in your HTML, use code like this:

<link href="/stylesheets/myStyle.css" media="all" rel="Stylesheet" type="text/css" />
   <script src="/javascripts/myJavascript.js" type="text/javascript"></script>

If possible, avoid tables

Tables used to be the main building block of Web pages, but now they're considered bad practice as page layout elements. Sometimes, you must use tables (and they're considered good practice for the display of tabular data). If you do, explicitly specify the widths and heights of the table cells, rows, and columns; otherwise, browsers have to perform many operations to calculate how to display them, which slows down page loading:

<td width="50px" height="10px">...</td>

Remove anything you don't need

Maybe this is the most obvious tip of all, but it is also one of the most frequently forgotten. I mentioned that "less is more": It's not only visually appealing to a broader spectrum of users, but it also means less stuff to download and process. If you really need to put a lot of stuff on your Web page, consider splitting the page into two, three, or more separate pages.

Tips for optimizing your Web pages

You can use several methods to optimize your Web pages, including compressing your JavaScript files, using Hypertext Transfer Protocol (HTTP) compression, and setting your image sizes.

Compress and minify your JavaScript files

JavaScript files can be quite impressive in size, which means that their download times can exceed that of all other components combined, in some cases. One approach to this problem is to compress JavaScript files. You can use GNU zip (gzip) to do so, because many browsers support this compression algorithm.

Another alternative is to minify. Minification removes from the code all the unnecessary characters, such as tabs, newlines, and spaces. It also removes comments left in the code and white spaces, further reducing the file size. You can use minification for both external and internal style sheets. The two most popular minification tools are JSMin and YUI Compressor (see Resources).

Use HTTP compression, and always use lowercase divs and class names

You can reduce the traffic between the server and the browser by using HTTP compression. You can configure HTTP compression in Apache (the .htaccess file), or you can include it in your pages (in the case of PHP, by using an HTTP_ACCEPT_ENCODING header). But beware: Not all browsers support compression. Even for those that do, compression and decompression loads the processor. To enable blanket—that is, all text and HTML—compression in Apache, use the following command:

AddOutputFilterByType DEFLATE text/html text/plain text/xml

Also, think about what you're trying to compress. Images, music, and videos are already compressed at the time of their creation, so you can limit your compression efforts to HTML, CSS, and JavaScript files.

One more trick to lessen the effort with compression is to use lowercase <div> elements and class names. Because case sensitivity and the fact that the compression scheme used is lossless, <header> is different from <Header> and is compressed as two different tags. In the following example, the Important class is different to the compressor than the important class, which means that to the compressor, they represent two different things and therefore are compressed individually as two different pieces of text.

<div class="Important">read this!</div>
<div class="important">This will cost you some valuable load time</div>

This attention to detail might not sound like a big deal. But when you're optimizing your files, every little bit counts— literally.

Set the image size

As with table cells, rows, and columns, when you don't explicitly set the image size, the browser needs to perform calculations to display the image, which slows down processing. Additionally, in certain cases, images sizes can be calculated incorrectly, and, as a result, the image might appear distorted.

Use CSS image maps for heavily used decorations

Using image maps instead of multiple images is another way to decrease load times, because downloading the separate parts of the image simultaneously speeds the download process for the whole page. Or, you can use something known as CSS sprites (see Resources.) CSS sprites help decrease the number of HTTP requests. A single image can hold all the image elements needed to decorate or lay out a page. You use CSS to choose (by calling certain positions and dimensions) which map is used for a particular element.

Delay your script loading, if possible

I mentioned earlier that not including JavaScript code you don't absolutely need speeds up loading and processing. But what if you have already cut to the bone and can't skip including JavaScript code on your page?

In this case, one of the possible ways to speed page download times is to put the script at the bottom of the page, so that the page loads more quickly. Often, browsers download no more than two parallel objects (from the same domain); if one of those objects is a piece of JavaScript code, the download of the other page components will halt until the script is downloaded. When you put the JavaScript code at the bottom, it will (in most cases) download last, after the other components.

Use the Firebug extension to trace which files load slowly, and I bet that your JavaScript files are among the slowest. Compressing JavaScript files helps, but it might be not all you need. You can defer JavaScript loading by using the following snippet:

var delay = 5;
setTimeout("heavy();", delay * 1000);

This code delays the call to the heavy() method for five seconds. You can use this code in combination with the next trick to delay the loading of the JavaScript file entirely.

Load JavaScript files on demand

To load JavaScript on demand, use the import() function, shown in Listing 3.

Listing 3. The import() function
function $import(src){
  var scriptElem = document.createElement('script');

// import with a random query parameter to avoid caching
function $importNoCache(src){
  var ms = new Date().getTime().toString();
  var seed = "?" + ms; 
  $import(src + seed);

Verify a function load

You can also verify that a function has been loaded and, if it hasn't, load the JavaScript file. To do so, use the code in Listing 4.

Listing 4. Verify that a function has loaded
if (myfunction){
  // The function has been loaded
else{ // Function has not been loaded yet, so load the javascript.

Note: You could use the defer attribute, but not all browsers— including Firefox— support it.

Optimize your CSS files

CSS files don't have to be large if you optimize and maintain them properly. CSS files with many orphaned classes, for example, affect download times. As with JavaScript files, you need to optimize your CSS files to include everything you need, yet be reasonable in size. Also, use external files rather than inline definitions to accommodate the browser's caching mechanism.

Use a content-distribution network

Content-distribution networks (CDNs) are another great way to improve download times. When you put your static images on many servers around the Internet, users can download them from whichever server is closer to them. Besides, most CDNs run on fast servers, so no matter how loaded the server is, it will still respond more quickly than a small, overloaded server.

Use multiple domains for your assets to increase connections

An additional advantage of CDNs is that they are a separate domain. Because your browser limits the number of concurrent connections to a single domain, whenever a page loads, it's easy to occupy all the threads. So, the connection to other assets is delayed. However, your browser can open new threads or connections to other domains; therefore, any asset loaded from another domain is loaded concurrently with all the other assets.

Use Google Gears when available

Using Google Gears (see Resources) is another great way to spare your users from downloading the same content over and over again. Gears allows users to access Web applications offline, but also allows for the persisting of page elements onto the user's computer. So, frequently loaded but not updated content could be stored in the Gears database, which is an SQLite3 relational database-management system. All next requests to the same content could be loaded directly from the database instead of from the server.

After you've installed Gears, get the gears_init.js file for easy access to the Gears factory and application programming interface (API), save it as gears_init.js, and reference it in your code as follows:

<script type="text/javascript" src="gears_init.js"></script>

To determine whether you have Gears installed, use the code in Listing 5.

Listing 5. Determine whether Gears is installed
  if (!window.google || !google.gears) {
    location.href = "http://gears.google.com/?action=install&message=<welcome message>" 
        + "&return=<return url>";

If you don't have Gears installed, the code presents you with the URL at which you can download it.

When everything is validated and Gears is installed, you can test the incredibly useful database feature of Gears by using the JavaScript code in Listing 6.

Listing 6. Test database features
<script type="text/javascript">
 var db = google.gears.factory.create('beta.db');
 db.execute('create table if not exists Test' +
           ' (Phrase text, Timestamp int)');
 db.execute('insert into Test values (?, ?)', ['Monkey!', new Date().getTime()]);
 var rs = db.execute('select * from Test order by Timestamp desc');

 while (rs.isValidRow()) {
  alert(rs.field(0) + '@' + rs.field(1));

This code creates a local database on your computer or server named db. Create a table named Test if it doesn't exist already, and insert some test data (Monkey! and the time). The code retrieves the data from the database and presents it as alerts in the browser.

Imagine the possibilities!

Use the PNG format for images

The Graphic Interchange Format (GIF) and Joint Photographic Experts Group (JPEG) image formats are past: Portable Network Graphic (PNG) is the format of the future. Of course, you can't say that GIF and JPEG are dead or that PNG doesn't have its disadvantages, but all things being equal, PNG provides good quality with an optimal file size. So, if you have the choice, use PNG images whenever possible.

Keep your Ajax calls short and to the point

When techniques collectively known as Asynchronous JavaScript + XML (Ajax) came along a couple of years ago, they provided a revolutionary method for handling page requests and responses. However, users on dial-up might never be able to experience its real advantages, because in many cases, Ajax requires a lot of communication between browsers and servers. So, if you can keep your Ajax calls short and to the point, you can prevent the user spending endless time waiting in vain for elements to refresh or respond.

Make one big Ajax call and handle the client data locally

If short Ajax calls aren't possible or if they don't provide the desired result, consider the alternative: one big Ajax call to get everything you need, then leave the client to process the data locally. In this way, the client waits once (to get the data in), but after that—when no communication between the browser and the server is necessary—things will process much more quickly. Of course, there's more to Ajax optimization than I can include in this tutorial. If you want to learn more about Ajax, see Resources.

Sandbox your coding

Here's another common-sense tip that's frequently forgotten. Although there is hardly a sane Web developer who doesn't test his or her applications before launching them, sometimes maintenance tasks get sidelined from testing or new features are added too quickly and without enough thought or testing. The result is that the rest of the script gets slowed down.

If you're adding a new function, try it out first in a sandbox—preferably completely outside the rest of the application—to see it behave as a single function. That way, you can check, recheck, and analyze performance and response times without having to cope with the rest of the Web application. Then, when the new function behaves as it should, you can introduce it into the rest of the application and run it against other tests, knowing that the feature itself behaves as expected.

Analyze your site code

Self-reflection is good advice on many fronts. Luckily, in the case of development, we have tools to help with this and make the practice as objective as possible. A tool like JSLint (see Resources) that, as the site proclaims, "may hurt your feelings", is invaluable because it presents you with all your potential code shortcomings—shortcomings that not only make for more challenging-to-debug problems but also for potentially longer response times.

Check your JavaScript code for errors or bad coding practices using JSLint

You don't have to be a perfectionist to try to make your JavaScript code look great. However, many developers don't take code analysis in earnest and often skip this step of the development process. Unfortunately, errors and bad coding practices are not only unprofessional but can also slow down your application. When the browser is fighting errors and bad coding practices, loading not only takes more time but can also lead to difficult-to-debug errors.

So, if you want your code to look good, consider using code-analysis tools. Different tools are available, but one of the best for the JavaScript language is JavaScript Lint, or JSLint (see Resources). You can also use Firebug, but JSLint is more pedantic, and it's included in YSlow.

Check for orphaned files and missing images

Checking for orphaned files and missing images is a wise thing to do. Most Web developers check bad file references, but it's worth mentioning. Missing files are problematic because they result in error messages such as "The image/page cannot be displayed." But in terms of Web page speed optimization, they have a larger disadvantage: When the browser is looking for a missing or orphaned file, it's consuming resources, which leads inevitably to slowing down page processing. So, run a check for orphaned or missing files, including misspelled file names.

The YSlow extension

The YSlow Firebug extension will make subjective Web page analysis a thing of the past. Using the definitive rules for high-performance Web sites as drafted by Yahoo!, YSlow analyzes Web pages and tells you why they're slow.

Analyze your pages using YSlow

YSlow is a relatively small but extremely useful Firefox extension. When you launch YSlow, the extension opens in the lower part of the browser, as shown in Figure 4.

Figure 4. The YSlow extension in Firefox
YSlow extension in Firefox

Figure 4 shows the Performance view, in which you see how YSlow rates the performance of your page along with whatever issues the extension has detected. Clicking a link in the list opens a page with explanations of the error. If there is a page component that you can improve, YSlow suggests improvements.

In the Inspect view, shown in Figure 5, you can dissect the page element by element. One of the most helpful features of the Inspect view is that it refreshes automatically when you move the mouse pointer over the page, so you don't have to scroll through long lines of code to find the line you need to inspect.

Figure 5. The YSlow Inspect view in Firefox
YSlow Inspect view

As you can guess from its name, the Stats view—shown in Figure 6—shows statistical data about the current page. This data includes empty and primed caches and cookies.

Figure 6. The YSlow Stats view in Firefox
YSlow Stats view

The Components view, which is shown in Figure 7, lists the components on the current page. The data displayed about each component includes the file type and path, when the page expires, and the HTTP response headers. Clicking a component opens that component for viewing. Click a column heading to sort the table in ascending or descending order.

Figure 7. The YSlow Components view
YSlow Components view

YSlow is a small, useful extension that can help you a lot in your efforts to make your pages load more quickly. If you haven't tried yet, you have no more excuses not to do so now.


Optimizing your Web pages for speed is hardly rocket science. In fact, you can often achieve speed optimization with minimal effort. If you follow the tips in this article along with Web development best practices, you won't have to go extra miles to make your pages load more quickly.

It never hurts to gather many page-optimization tips in one place, and I hope this article provides a valuable resource. However, if you think that the list of speed optimization starts and ends with the tips presented here, you're in for a surprise. But even if you follow just these 20+ tips, your pages will load more quickly and your users will be happier—no matter whether they run on dial-up or on a dedicated broadband line.



Get products and technologies

  • Minify your JavaScript files to the absolute minimum with JSMin.
  • YUI Compressor is Yahoo!’s JavaScript compressor and part of the Yahoo! UI Library. This site also provides excellent reading into the different aspects that go into compressing code in general and how the ideal code obfuscates side effects.
  • JSLint helps you identify bad coding practices.
  • Firebug is a Firefox add-on that puts a wealth of development tools at your fingertips.
  • Discover and download Google Gears.
  • YSlow is a Firebug add-on developed by Yahoo! that analyzes your pages and tells you why they are slow.



developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into Web development on developerWorks

Zone=Web development
ArticleTitle=Speed up your Web pages