Building faster websites by reducing HTTP requests: three techniques

http requests One of the best practices to follow for making a speedy website is to reduce the number of HTTP requests needed. Every HTTP request for an HTML file, image, SWF, CSS or Javascript page adds a small penalty to page loading. Moreover, often only two connections can be made to a single server simultaneously, although this limit has been increased on more recent browsers. On graphically rich modern sites using JS and CSS frameworks, the number of requests can multiply rapidly! Here are some techniques we've used to deal with the problem.

The first step is to find out exactly what requests a page requires. Clear your browser cache, then load up the page. Using Firebug for Firefox or a proxy like Charles you can see exactly what HTTP requests are being made. Here are some common sources of multiple requests.

Problem 1: too many jQuery plugins. Solution: combine JS files!

jQuery is a powerful Javascript framework, which can be extended with a large variety of plugins. But if you're not careful, your <head> can end up looking like this:

  1.  
  2. <script type="text/javascript" src="/js/jquery-1.3.min.js"></script>
  3. <script type="text/javascript" src="/js/jquery.validate.min.js"></script>
  4. <script type="text/javascript" src="/js/jquery.timeago.js"></script>
  5. <script type="text/javascript" src="/js/jquery.scrollTo-min.js"></script>
  6. <script type="text/javascript" src="/js/jquery.annotate.js"></script>
  7. <script type="text/javascript" src="/js/jquery-ui-1.7.custom.min.js"></script>
  8. <script type="text/javascript" src="/js/jquery.lightbox-0.5.min.js"></script>
  9.  

Ouch! A new visitor to the site will have to make 7 HTTP requests just to get the Javascript. There are various options for combining these files. Perhaps the simplest is to make a small batch file or shell script.

Here's how to do this in Windows. TYPE displays a text file, and the >> operator appends the file to the target. Create a file called combine-javascript.bat containing these lines:

TYPE jquery-1.3.min.js >> jquery.and.plugins.js
TYPE jquery.validate.min.js >> jquery.and.plugins.js
TYPE jquery.timeago.js >> jquery.and.plugins.js
TYPE jquery.scrollTo-min.js >> jquery.and.plugins.js
TYPE jquery.annotate.js >> jquery.and.plugins.js
TYPE jquery-ui-1.7.custom.min.js >> jquery.and.plugins.js
TYPE jquery.lightbox-0.5.min.js >> jquery.and.plugins.js

Place this batch file in your JS folder, run it and it will generate a combined Javascript file.

Here's how to accomplish the same task with bash on Linux:

  1.  
  2. cat jquery-1.3.min.js >> jquery.and.plugins.js
  3. cat jquery.validate.min.js >> jquery.and.plugins.js
  4. cat jquery.timeago.js >> jquery.and.plugins.js
  5. cat jquery.scrollTo-min.js >> jquery.and.plugins.js
  6. cat jquery.annotate.js >> jquery.and.plugins.js
  7. cat jquery-ui-1.7.custom.min.js >> jquery.and.plugins.js
  8. cat jquery.lightbox-0.5.min.js >> jquery.and.plugins.js
  9.  

Now we can replace all our script tags with:

  1.  
  2. <script type="text/javascript" src="/js/jquery.and.plugins.js"></script>
  3.  

An alternative is to combine the files dynamically, perhaps using a PHP script. If you choose this method, you'll need to ensure the Content-type of the response is set to text/javascript and that caching headers are sent correctly (see below).

Problem 2: too many images. Solution: CSS sprites!

Many Annas

Although each image may be small, multiple small images can really slow down your site. One solution is CSS sprites. This is a technique which combines related images into a single large image. By carefully setting the background-position attribute in CSS, you can show exactly the part of the large image that you need. Here's the original A List Apart article which introduced CSS sprites.

You can see an advanced version of this in action on our funky about us page. We took photos of each team member facing in different directions, then joined them into a long strip like this: . Javascript is then used to pull the correct part of the image into place.

Problem 3: same file requested multiple times. Solution: Add an Expires HTTP header!

Navigate to a few pages on your site. Are you seeing requests for the same CSS or JS files repeatedly? If so, you need to check the HTTP headers being sent with these files. If the browser receives an Expires header like this:

Expires: Sat, 17 Apr 2010 12:00:00 GMT

then it knows not to request this resource again for one year. How to configure this depends on your server, a quick Google search will provide the information you need.

But what if you actually DO want to change the file later? The simplest way is to add a querystring containing a version number, like this

  1.  
  2. <link rel="stylesheet" href="/css/corporatestyle.css?v=1" type="text/css"
  3. media="screen, projection" />
  4.  

If the corporate style changes to require, say, purple headlines, then a quick change to

  1.  
  2. <link rel="stylesheet" href="/css/corporatestyle.css?v=2" type="text/css"
  3. media="screen, projection" />
  4.  

will ensure that the browsers download a new copy of the file on the next visit. Combine this with a Expires date in the far future and you have the best of both worlds.

Further reading

For more on this topic and further suggestions, visit the Yahoo Developer Network's best Practices for Speeding Up Your Web Site

Post a Comment