Speed Up Your Website by Reducing HTTP Requests

I finally got around to optimizing my website, and boy did it need it. I wish read an article like this beforehand – I would have saved myself time. If you’re a web designer or developer, this article could help you too. In this article, I’ll show you how to speed up your website by reducing HTTP requests using sprite sheets and combining and minifying Javascript and CSS – Easily.

Using the techniques in this article, I increased the speed of my website tremendously. If you’re reading this, you’re already interested in reducing HTTP requests, so I’m not going to go into why it’s important. For a quick refresher, here is Yahoo’s take on reducing HTTP requests, and Google’s explanation of what goes into each HTTP request.

Let’s look at how I reduced HTTP requests on my website, using my homepage as an example. Then we’ll get into details that can be applied to any site.

Before Optimization

According to YSlow, I was already doing a pretty good job on my homepage. It gave it an “A” overall using the blog site rules. However, I had neglected the overhead of HTTP requests for desktop users (it just wasn’t high enough on the priority list to make my launch date). Here is a pre-optimization snapshot of YSlow’s opinion of the desktop version of my homepage:

Yikes! Look at all those HTTP requests: That’s 10 Javascript + 5 stylesheets + 15 background images for a total of 30 requests. YSlow gives me an “F”, in this category – as well it should. Needless to say, I followed YSlow’s advice and combined my images into sprite sheets, and combined my Javascript and CSS. Before we look at how I did it, let’s discuss how I use images on my homepage.

Images on My Homepage

For my homepage, almost all of the background image requests originate from an animation slider only visible to desktop users. For tablet and phone users, a media query prevents animation image downloads, because animation is not used in my homepage for smaller viewports (the slider switches over to static images).

The challenge that was unique to combining images for my animation slider was in the nature of the animations. In my animations, as time goes by, more images appear (they are progressively added to the DOM by my animator script). Some images need to be available immediately, while others don’t need to be available until the animation has progressed a while.

Before I optimized, my animator just downloaded the images at the moment they were needed. This sometimes resulted in the loss of fading and sliding effects for first time visitors because the images might not be available at the start of the effect. To fix this, I combined images that needed to be available near the same time into sprite sheets and pre-loaded them for future animations during lulls in the animation sequence.

Multiple Benefits Using Sprite Sheets

Sprite sheets not only improve the speed at which your page loads by reducing the number of HTTP requests, this technique can also be used to improve the performance of animations after your page has initially loaded. The iPhone 5 design website is a great example of using sprite sheets for animation. But this article is about reducing HTTP requests, not animation. So let’s get on with how to create sprite sheets for any website!

Creating Sprite Sheets using Compass

If you don’t already know about Compass, that’s fine. Just know it’s a free tool that you can use to ease the pain and suffering of authoring CSS by hand. Compass is a CSS authoring framework, written in Ruby, so you’ll need to install Ruby before it will work. However, I’m confident after I walk you through how to automatically generate sprite sheets and the CSS that uses them, you will be motivated to learn more about this awesome tool. The sprite sheet is just one of countless web patterns Compass, and its many extensions, automate. Here is a walkthrough of how to use Compass to automatically generate sprite sheets, using the linux command line as an example.

Compass Sprite Sheet Creation Walkthrough

Step 1: Create a Compass Project

To create a compass project, on the command line, go to the directory under which you want to create the project and type:
compass create myproject

This creates a project called “myproject”. It also creates the following directories and files:

myproject
   config.rb
   sass
      ie.scss
      print.scss
      screen.scss
   .sass-cache
   stylesheets
      ie.css
      print.css
      screen.css

Looking at the config.rb, we see the following definitions:

http_path = "/"
css_dir = "stylesheets"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"

So go to the “myproject” directory, and create a directory called “images”, matching the images_dir variable in the config.rb. Now your project directory structure should look like this:

myproject
   images
   sass
   stylesheets

Step 2: Copy Your Images

Create a sub-directory under the “images” directory for each sprite sheet you want to create. Here, I’ve just created one called “mysprites”:

myproject
   images
      mysprites
   sass
   stylesheets

Now, just copy over the images you want to combine into the sprite sheet. Compass only supports png format, so if your images aren’t already pngs, you’ll have to convert them too. I suggest using Gimp. These will be your image sprites:

myproject
   images
      mysprites
         image1.png
         image2.png
         etc...
   sass
   stylesheets

Step 3: Start Compass

Run Compass in the background to watch for changes in the project. When your project changes, it will automatically work its magic. From the “myproject” directory, run the following command:
compass watch &

Of course, you could manually run compass after you write the code for the same effect, but its just so much more magical (and easy) when its automatic. :-)

Step 4: Write 4 Lines of Code

In myproject/sass/screen.scss, add the Sass code to generate the sprite sheet and the CSS required to access the images. Here is an example of the Sass code required for screen.scss to generate the sprite sheet and CSS for “mysprites”. In this example, I also direct Compass to generate the image dimensions and add some padding around the sprites:

$mysprites-sprite-dimensions: true; /* include dimensions in CSS */

$mysprites-spacing: 10px; /* include padding for every sprite */

@import "mysprites/*.png"; /* generate a sprite sheet for mysprites */

@include all-mysprites-sprites; /* generate CSS for all sprites */


Padding is required for sprites because some browsers will do funky stuff (they’ll show the beginnings of surrounding images in the sprite sheet) when the user zooms in or out of your web page. Be sure to add a enough padding to avoid strangeness in case your users do this.
Of course, you can get much more fancy than this example. An explanation of all of the global and per-sprite options is available in the Compass tutorial.

Step 5: Save the File

Since you previously set up Compass to watch for changes, it will automatically create the sprite sheet in the “images” directory for “mysprites” and generate the required CSS in myproject/stylesheets/screen.css. The CSS will contain classes to download the sprite sheet, and the individual classes to access each individual image from within it. No math required!

Step 6: Enjoy

This whole process generated two pieces of output, a sprite sheet and the CSS to use it. The generated sprite sheet can be found in the “images” directory, and the CSS is in the “stylesheets” directory:

myproject
   images
      mysprites-sa05beb30ad.png
   stylesheets
      screen.css

Here is an example of the CSS output for “mysprites”, found in screen.css:

.mysprites-sprite, .mysprites-image1, .mysprites-image2 {
  background: url('/images/mysprites-sa05beb30ad.png') no-repeat;
}

.mysprites-image1 {
  background-position: 0 0;
  height: 167px;
  width: 236px;
}

.mysprites-image2 {
  background-position: 0 -287px;
  height: 120px;
  width: 60px;
}

Now you are free to use the sprite sheet and the CSS on your website. You’ll save yourself lots of HTTP requests by bundling images together and downloading them all at once.

Combining and Minifying Javascript and CSS

Now that you’ve seen how easy it is to speed up your website using a sprite sheet, lets see how easy it is to combine and minify Javascript and CSS to reduce HTTP requests. The basic idea is to move all the CSS and Javascript referenced on your site into small files, one for all the javascript, and one for all the CSS. This may not be possible (or desirable) for some of your Javascript, depending on what you are doing.

Of course, there are many ways to do this (including by hand), but I wanted to select the easiest, most maintenance-friendly way to get this done. With those goals in mind, and since I’m a WordPress guy, I chose to go with WP-Minify.

WP-Minify

WP-Minify by combines and minifies your CSS and Javascript (and even your HTML too). It seems pretty awesome to me at the moment, and it seems to play well with my other plugins. To get the benefits, I just installed this plugin, activated it, and left it on the default settings.

The beauty of WP-Minify is that it combines and minifies my Javascript, CSS, and HTML when WordPress is creating the website output for a request. So I don’t have to go back and re-structure my development workflow, I just have to maintain the WP-Minify plugin. This doesn’t have an additional performance penalty for my site because I only serve cached, compressed files – but that is another optimization topic altogether.

When I reviewed my gains with YSlow, I saw that I had achieved what I was looking for:

YSlow still thinks I’m only doing “C” work with regard to HTTP requests, but it also doesn’t know about my progressive downloads either (when my page initially loads, there are only 3 HTTP requests for background images). In the snapshot above, YSlow is evaluating my requests after my entire animation has run.

However, now I have only 8 external Javascript files and 8 background images in total on my homepage. So I have cut my HTTP requests (almost) in half using sprite sheets and WP-Minify. This is a big improvement, and for now I have to stop here. YSlow now gives me a strong A for a small blog site, and the Google PageSpeed tool agrees.

Hopefully this article is useful to you. There are many things you can do to speed up your website, and reducing HTTP requests is just one important thing you can do. Please let us know if this is helpful, and/or if you are interested in more website performance optimization tips.

Of course, you can always contact LocalNerve if you need advice on improving the performance of your website. We’re happy to help!

One thought on “Speed Up Your Website by Reducing HTTP Requests

Leave a Reply

Your email address will not be published. Required fields are marked *

*