Published: 27 Apr 2011
By: Scott Mitchell
Download Sample Code

Because browsers limit how many concurrent HTTP requests they make to a website, a web page with many small icon images can result in a longer load time. This article shows how to combine many small images into a single larger image - a CSS sprite - using the free ASP.NET Sprite and Image Optimization Library available from Microsoft.

Contents [hide]

Introduction

Whenever a browser visits a web page it downloads both the page's markup and any external resources specified in the page. These external resources include images, JavaScript files, and CSS files, among others. In general, the more external resources a web page has the longer it will take to completely load because each external resource requires an additional HTTP request from the browser. A common technique for improving website performance is to combine multiple resources into a single file. In their guideline, Best Practices for Speeding Up Your Web Site, Yahoo! notes: "Reducing the number of HTTP requests in your page is the place to start. This is the most important guideline for improving performance for first time visitors."

To improve load times, consider using inline images. Inline images are images whose binary content is specified directly in the markup as a base- 64 encoded string, either in the page's <img> element or in a CSS file. This technique folds the image into the web page (or CSS file), thereby eliminating the need for the browser to make a separate request to download the image. CSS sprites are another common technique for reducing the number of HTTP requests needed to load images. In short, a sprite is an image file that is a conglomoration of many images. To show a particular image from the sprite the <img> element specifies CSS rules – namely, width, height, and background-position – that display just the portion of the sprite that corresponds to the image of interest.

Traditionally, using inline images required calculating the base-64 encoded string and pasting that into your markup or CSS file, while using CSS sprites involved combining the shared images into a sprite and writing CSS rules to "slice and dice" the sprite to display the intended image. The good news is that using inline images and CSS sprites in an ASP.NET WebForms or MVC application is now easier than ever thanks to Microsoft's free ASP.NET Sprite and Image Optimization library. The Spite and Image Optimization library:

  • Can automatically render inline images by computing and emitting the image's base-64 encoded string
  • Automatically combines multiple images into sprites,
  • Generates the CSS files needed to display the inline images and the images contained within a sprite, and
  • Includes both a Web control and an HTML Helper to simplify displaying inline images and images from a sprite.

This article explores the benefits of using inline images and CSS sprites to reduce the number of HTTP requests that must be made when loading it page. It also shows how to use the Sprite and Image Optimization library in both WebForms and MVC applications.

Warning: Beta Software Ahead

At the time of writing the ASP.NET Sprite and Image Optimization library is still in beta. This article and its accompanying download use the most up-to-date version of the beta software (Preview 3) as of the time of writing. You are encouraged to visit the ASP.NET Sprite and Image Opimization library's project page to see if there is a new version available.

Getting Started

To start using the Sprite and Image Optimization library, visit the project page and download the most recent version. You can download either the pre-compiled binaries or the library's source code. The binary download includes three assemblies:

  • Microsoft.Web.Samples.ImageOptimizationFramework.dll
  • Microsoft.Web.Samples.ImageSprite.dll
  • Microsoft.Web.Samples.SpriteHelper.dll

The Microsoft.Web.Samples.ImageSprite assembly includes the ImageSprite Web control for WebForm applications, while the Microsoft.Web.Samples.SpriteHelper assembly includes the HTML Helper for MVC applications. Consequently, you'd only add the former to a WebForms application and the latter to an MVC application. The Microsoft.Web.Samples.ImageOptimizationFramework assembly contains the guts of the library and must be added to your project regardless of whether its a WebForms or MVC project.

NOTE

The download accompanying this article includes both WebForms and MVC demos.

WebForms ConfigurationIf you are using the library in a WebForms application start by adding a reference to the Microsoft.Web.Samples.ImageOptimizationFramework and Microsoft.Web.Samples.ImageSprite assemblies.

Next, add the following content to your Web.config file:

Listing 1: For WebForms applications, add the following configuration to your Web.config file.

The system.web\pages\controls section registers the ImageSprite Web control so that it can be used in your ASP.NET pages. The Displaying the Optimized Images section looks at using this Web control.

The system.web\httpModules and system.webServer\modules sections register the HTTP Module that is responsible for converting the images you specify into one or more CSS sprites and for generating the accompanying CSS files. Note that the system.web\httpModules section is used by the ASP.NET Development Web Server and IIS version 6 and earlier, whereas the system.webServer\modules section is used by IIS Express and IIS 7. It doesn't hurt to add both sections, although depending on your configuration only one section may be necessary.

ASP.NET MVC ConfigurationIf you are using the library in an ASP.NET MVC application, start by adding a reference to the Microsoft.Web.Samples.ImageOptimizationFramework and Microsoft.Web.Samples.SpriteHelper assemblies. Next, add the following configuration to the Web.config file in the Views folder.

Listing 2: For ASP.NET MVC applications, add the Microsoft.Web.Samples namespace to the View folder's Web.config file.

You do not need to add any configuration to the Web.config file in the application's root folder.

Examining the Default Behavior

The demos accompanying this article have six small icons that I downloaded from famfamfam:

  • Accept.png
  • Add.png
  • Email.png
  • Page_excel.png
  • Page_word.png
  • User.png

In one web page, each of these images is rendered in the traditional way –an <img> element that specifies the URL of the image to display in its src attribute. Here is the markup used in the ASP.NET MVC application to display the images; the WebForms demo (not shown here) uses six Image Web controls whose ImageUrl properties are assigned the URLs of the image to display.

Listing 3: Each image is displayed using an <img> element.

Figure 1 shows the output of this page when viewed through a browser.

Figure 1: Each of the six images is displayed in the traditional way, requiring a separate HTTP request for each.

Each of the six images is displayed in the traditional way, requiring a separate HTTP request for 

each.

When a browser loads this page it must make seven separate HTTP requests: one for the web page and then one for each of the six images. Figure 2 shows a screen shot from Firebug that illustrates these seven HTTP requests.

Figure 2: Each image requires a separate HTTP request.

Each image requires a separate HTTP request.

Displaying Images Using Inline Images

Traditionally, images are stored on the web server and are referenced in a web page via an <img> element. Specifically, the <img> element's src attribute specifies the location of the image data, which the browser then downloads and displays. Inline images allow you to specify the image's binary data directly in the web page as a base-64 encoded string.

The following markup shows how to use an inline image directly in the <img> element.

Listing 4: An inline image's binary content is specified directly in the markup.

Image inlining can also be done via a CSS rule. The following rule defines a 16x16 icon image and specifies the image's content directly in the CSS markup. To display the image defined you'd simply create an <img> element and set its class to my-image.

Listing 5: The inline image's content is defined directly in the CSS.

The benefit of inline images is that they avoid additional HTTP requests from the browser. The primary drawback is that there is not universal support for inline images. While inline images are supported in Internet Explorer 9, they are not supported in earlier versions of IE. Likewise, inline image support wasn't added to Firefox until version 3.5.

Displaying Images Using CSS Sprites

A CSS sprite is a single, large image that is comprised of multiple smaller images. Figure 3 shows a single sprite that combines the six individual icons displayed in Figure 1. Bear in mind that the sprite is a single image file. In the case of Figure 3, it's a file that 102 pixels wide and 16 pixels high.

Figure 3: The six image files are automatically combined into a single sprite.

The six image files are automatically combined into a single sprite.

Of course, we are not interested in displaying the entire CSS sprite as one image; instead, we need to show a particular subset of the image. In the case of the sprite in Figure 3, we want to display a single 16x16 image.

To display a particular image from the conglomorate, CSS rules such as width, height, and background-position are used to define a viewport on the image. For example, to display the email icon we would use the following CSS rules and <img> element markup:

Listing 6: The CSS rules to display the email icon from the CSS sprite my_sprite.png.

The width and height rules define the dimensions of the viewport. The background-image rule specifies the URL to the sprite, while the background-position rule specifies the offset from where the viewport starts.

Optimizing Images with the Sprite and Image Optimization Library

The Sprite and Image Optimization library will auto-optmize images by using image inlining or CSS sprites depending on the library's configuration and the browser visiting the page. But it will only optimize those images that reside in a special folder, App_Sprites. The first order of business, then, is to add whatever images you want to optimize to this special folder. In the demos avaialble for download I created an App_Sprites folder and copied the six image icons listed in the Examining the Default Behavior into this folder.

Not All Files are Candidates for Inline Images and CSS Sprites

Inline images and CSS sprites are an ideal way to reduce the number of requests a browser must make to load a page and its images, but not all images are good candidates for these types of image optimizations. In general, inlined images and sprites are ideal for small decorative images that are used on many pages. Inlined images and CSS sprites should not be used for large images or for images that represent contextual content.

For example, Amazon.com uses a single CSS sprite to hold their rating stars, their site logo, their various "Add to Cart" buttons, and other icon images, including an email icon, an RSS feed icon, and so forth. However, they do not use sprites for content images, such as book covers, product snapshots, and so on.

On the first visit to your website after adding or deleting images from the App_Sprites folder, the Sprite and Image Optimization library automatically creates one or more CSS sprites from the images in the folder. For instance, the Sprite and Image Optimization library combined the six separate images displayed in Figure 1 into a single PNG file, sprite0.png (see Figure 3).

In addition to creating the sprite(s), the library also generates two CSS files:

  • highCompat.css
  • lowCompat.css

The auto-generated sprite(s) and CSS files are created in the App_Sprites folder.

How many sprites are created, their format, and the rules present in the generated CSS files depend on the library's configuration. For instance, if the Sprite and Image Optimization library is configured to support inline images then the highCompat.css CSS file defines a class for each image that contains the image's base-64 encoded binary content. On the other hand, the lowCompat.css CSS file defines the rules for displaying the particular image from within the sprite. (If the library is configured such that inline images are disabled then both the highCompat.css and lowCompat.css files contain the same rules, namely those for displaying the images from within the sprites.)

There are six configuration options:

  • FileFormat – indicates the sprite image format and can be one of either: JPG, GIF, BMP, or PNG (the default).
  • Quality – specifies the compression level for JPG sprites. The default is 80.
  • MaxSize – the maximum size in kilobytes for a sprite image. If the combined size of the images in the App_Sprites folder exceeds this threshold then multiple sprite files are created. The default is 450.
  • BackgroundColor – the background color of the sprite, specified in ARGB format. By default, a transparent background color is used (00000000).
  • Base64Encoding – indicates whether to enable inlined images. The default is true.
  • TileInYAxis – determines whether the sprite tiles images along the X axis (side-by-side) or Y axis (one above the other). By default, this value is false. Set this value to true if your images have differing heights but the same widths, as tiling along the Y axis may result in a smaller sprite.

To override the default values create a file named settings.xml and place it in the App_Sprites folder. The demos available for download include a settings.xml file with the default values specified (see Listing 7).

Listing 7: You can override the default configuration by adding a settings.xml file to the App_Sprites folder.

Displaying the Optimized Images

Displaying an optimized image requires:

  1. Adding a link to the appropriate CSS file, highCompat.css or lowCompat.css, and
  2. Adding an <img> element whose class attribute is assigned the appropriate CSS class name defined in the highCompat.css or lowCompat.css file.

In short, the <img> element does not reference an image directly; instead, it references a CSS class that defines the image source, either as an inline image or as part of a sprite.

In a Web Forms application, use the ImageSprite Web control to display an optimized image from the the App_Sprites folder. Listing 8 contains a portion of the markup from a web page that displays the six optimized images. Note that rather than using Image Web controls to dispaly each image we use the ImageSprite Web control.

Listing 8: Use the ImageSprite Web control to display an optimized image in a WebForms application.

The ImageSprite Web control renders and <img> element with the appropriate markup, which we'll examine shortly. It also automaticlly adds a link to the appropriate CSS file, either highCompat.css or lowCompat.css, depending on the user's browser. Specifically, the lowCompat.css CSS file is linked when visiting with Internet Exporer 7 or 8 or Firefox 3.0 or earlier; highCompat.css is used for Internet Explorer 9 and above, Firefox 3.5 and above, and all other browsers (Chrome, Safari, Opera, etc.).

In an ASP.NET MVC application, use the Sprite.Image HTML Helper to display optimized images (see Listing 9).

Listing 9: Use the Sprite.Image HTML Helper to display an optimized image in an ASP.NET MVC application.

Unlike the ImageSprite Web control, the Sprite.Image HTML Helper does not automatically add a link to the appropriate CSS file. Instead, you need to add this link yourself using the Sprite.ImportStylesheet HTML Helper, which would go in your master page's <head> section.

Listing 10: Use the Sprite.ImportStylesheet HTML Helper to add a link to the appropriate CSS file.

Don't Forget These Important Configuration Steps!

To use the ImageSprite Web control in your WebForms application you need to add a reference to the Microsoft.Web.Samples.ImageSprite assembly and register the control in the Web.config file.

To use the Sprite.Image HTML Helper in your MVC application you need to add a reference to the Microsoft.Web.Samples.SpriteHelper assembly and include the Microsoft.Web.Samples namespace in the View folder's Web.config file.

These configuration steps were covered in the Getting Started section.

The ImageSprite Web control and Sprite.Image HTML Helper render an <img> element with the following format.

Listing 11: The element emitted by the ImageSprite Web control.

The <img> element's class attribute is the workhorse here, indicating the CSS class where the image's details are stored. (While the src attribute does specify inline image content, this content is merely a 1 pixel wide by 1 pixel tall transparent GIF image.) If the highCompat.css CSS file is referenced - and if the library has been configured to support inlined images - then the image's binary contents are defined directly in the CSS file's accept-png class, as Listing 12 shows.

Listing 12: The base-64 encoded content of the accept.png image is defined directly in the highCompat.css CSS file.

In Examining the Default Behavior we looked at the HTTP traffic for a web page that contains six unoptimized images. Recall that this page required seven HTTP requests in total – one for the web page and one for each of the six images. When displaying optimized images using inlined images the HTTP traffic required to load the page drops from seven requests to two. The browser no longer needs to make separate requests for each image; instead, a single request to the the highCompat.css CSS file returns the binary contents for all six images on the page (see Figure 4).

Figure 4: Only two HTTP requests are needed to display any number of optimized images – one for the page and one for the highCompat.css file.

Only two HTTP requests are needed to display any number of optimized 

images – one for the page and one for the highCompat.css file.

If the Sprite and Image Optimization library has been configured to disable inlined images or if the user is visiting from a browser that does not support inlined images then CSS sprites are used instead. When using sprites the image's associated CSS class specifies the sprite via the background-image rule; the dimensions of the viewport to show the image of interest from within the sprite are specified via the width, height, and background-position rules. Listing 11 shows the CSS rules for the accept-png class when inlined images are disabled or not supported.

Listing 13: When using sprites the CSS rules specify the sprite image and how to extract the image of interest from the sprite.

In the case of CSS sprites, three HTTP requests are required for a page displaying optimized images: one for the web page, one for the CSS file, and one for the sprite (see Figure 5).

Figure 5: When using CSS sprites, three HTTP requests are required to load the page and images.

When using CSS sprites, three HTTP requests are required to load the page and images.

Conclusion

Inline images and CSS sprites are two techniques for improving web page load times by reducing the number of HTTP requests a browser must make to load a page. The primary challenge of using these techniques lies in creating the sprites and CSS rules. The ASP.NET Sprite and Image Optimization library is a free, open-source library from Microsoft that simplies working with inline images and CSS sprites by automatically creating the sprites and CSS rules. This article showed how to get started with the Sprite and Image Optimization library in WebForms and MVC applications.

Happy Programming!

Further Reading

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Scott Mitchell

Scott Mitchell, author of eight ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott works as an independent consultant, trainer, ...

This author has published 16 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
jQuery Mobile ListView
In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
Exception Handling and .Net (A practical approach)
Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
JQuery Mobile Widgets Overview
An overview of widgets in jQuery Mobile.
Book Review: SignalR: Real-time Application Development
A book review of SignalR by Simone.
Top
 
 
 

Discussion


Subject Author Date
placeholder Great article john theman 5/7/2011 11:53 AM
Take a look at RequestReduce for auto spriting and optimization including css merging and minification Matt Wrock 9/15/2011 10:01 AM
placeholder Question Koti Kot 2/1/2012 11:49 AM

Please login to rate or to leave a comment.