ASPNET Image Optimization

21
Image Optimization in ASP.NET How to use built-in support for CSS sprites and base64 image inlining to make your site load images faster Morgan McLean Microsoft Corporation 7

Transcript of ASPNET Image Optimization

Page 1: ASPNET Image Optimization

Image Optimization in ASP.NETHow to use built-in support for CSS sprites and base64 image inlining to make your site load images faster

Morgan McLeanMicrosoft Corporation

7

Page 2: ASPNET Image Optimization

Table of ContentsIntroduction.........................................................................................................................................2

The Performance Penalty of HTTP Requests...........................................................................................2

Reducing the Number of HTTP Requests..............................................................................................3

Sprites......................................................................................................................................................3

How Sprites Work................................................................................................................................................4

Image Inlining Using Base-64 Encoding...................................................................................................6

Disadvantages of Inlines Images.........................................................................................................................6

Comparison of Sprites and Inlining.......................................................................................................7

Browser Compatibility.............................................................................................................................7

When to Use Image Optimization Techniques......................................................................................7

Optimizing Images in ASP.NET..............................................................................................................8

Installing and Configuring the ASP.NET Image Optimization Framework...............................................8

Preparing Images for Optimization.......................................................................................................9

Adding Images to the App_Sprites Folder...............................................................................................9

Configuring Optimization Settings...........................................................................................................9

How ASP.NET Image Optimization Works...........................................................................................10

Monitoring App_Sprites for Changes.....................................................................................................10

How Images Are Displayed by the Built-In Controls..............................................................................11

Adding Optimized Images to a Page...................................................................................................11

ASP.NET Web Forms Control.................................................................................................................12

ASP.NET MVC and Razor Helper............................................................................................................12

Raw HTML Markup................................................................................................................................12

Image Optimization Quick Reference.................................................................................................13

Static Fields............................................................................................................................................13

Public Methods......................................................................................................................................13

Disclaimer..........................................................................................................................................15

Image Optimization in ASP.NET 1© 2010 Microsoft Corporation

Page 3: ASPNET Image Optimization

Introduction

The ASP.NET image performance optimization framework is designed to decrease the amount of time required to request and display a page from a web server by performing a variety of optimizations on the page’s images.

The Performance Penalty of HTTP Requests

With the prevalence today of high speed Internet connections, page load speeds are no longer primarily limited by the amount of content that must be downloaded by a web browser. Instead, a limiting factor is the latency caused by the HTTP requests that are needed in order to download each piece of external content on a page. Because images are the most frequently used external elements in web pages, a significant portion of the time required for a web browser to fully load a page is spent sending HTTP requests to the server to download each individual image file. This is particularly true if a page contains many small images, as shown in Figure 1.

Figure 1: Pages on the Northwind Online site include a large number of small images. Without image optimization, these images would cause page to load slowly as the browser

requests each image individually.

Most browsers and web servers are configured to allow anywhere between two to six HTTP connections at a time. This causes the HTTP request latency to significantly impact the amount of time that it takes to load a web page that contains many images, because only a limited number of requests can be processed in parallel, as shown in Figure 2:

Image Optimization in ASP.NET 2© 2010 Microsoft Corporation

Page 4: ASPNET Image Optimization

Figure 2: A partial analysis of the time spent loading a popular technology news site. The X-axis is the running time, and each piece of content is given its own horizontal series.

The graph in Figure 2 shows how inefficiently most web browsers download image-heavy pages. On each data series, the light purple section displays the latent time required to initiate each download, while the smaller dark purple segments indicated the actual download time. Additionally, there is a limitation on how many downloads can take place at the same time, which defeats the possible advantages of many images loading in parallel. The grouping of smaller image downloads in the red circle shows how this limitation is particularly wasteful, because each download spends more time waiting for an HTTP response than actually streaming the image data.

You can see that reducing this inefficiency can provide large benefits in terms of reduced time waiting for pages to load. It can also diminish the load on the content provider’s server and network as well, because the reduced number of HTTP requests lessens the work for load balancers.

Reducing the Number of HTTP Requests

To reduce the number of HTTP requests that a page requires in order to fetch all the images it needs, you can use two methods: sprites and image inlining.

Sprites

A sprite is a collection of graphics combined into a single image file, from which you can extract individual images using their grid location and size. Using sprites instead of collections of discrete images goes back to the era of 8-bit video games, where programmers found that by merging all of a game’s individual bitmaps into a single grid-style file, they could significantly reduce the amount of memory

Image Optimization in ASP.NET 3© 2010 Microsoft Corporation

Small interface images – much of the time it takes to download each is simply due to latency

Page 5: ASPNET Image Optimization

required to display graphics content. In particular, sprites were efficient because they required only one color palette for the entire graphic, rather than a separate color palette for each individual image. Figure 3 shows how this was done:

Figure 3: An example of a sprite sheet from an 80’s style game. By combining many small images into a single file, programmers were able to save significant amounts of memory.

(Figure credited to The Sprite Artists of Game Design Novice.)

The same concept can also be applied to web design. In addition to reducing the file size of the images placed on a page (because of the palette issue), using a sprites also reduces the number of HTTP requests that are required in order to load set of images to just one request (plus one additional request for a required CSS file).

How Sprites Work

To work with sprites, you (or a designer) must merge a collection of images into a single image file, as shown in Figure 4.

Figure 4: A collection of Microsoft icons (on the left) is merged into a single sprite image

After the page and sprites have been downloaded to a browser, the browser can use the individual images in the sprites through settings from the CSS background-position, width, and height descriptors. These settings let you slice an individual image out of a sprite sheet, which is referenced as the value of the CSS background-image property. The following figure shows CSS rules that include background-image descriptors. Notice that in each case the descriptor points to the same image, url(sprite0.png), which is the sprite that contains the combined smaller images. However, each rule includes distinct dimensions for background-position, width, and height settings.

Image Optimization in ASP.NET 4© 2010 Microsoft Corporation

Page 6: ASPNET Image Optimization

.azureLogo-png{width:123px;height:115px;text-decoration:none;display:block;background-image:url(sprite0.png);background-position:-0px 0;}I .dotNet-png{width:310px;height:155px;text-decoration:none;display:block;background-image:url(sprite0.png);background-position:-123px 0;}.exchange-png{width:119px;height:138px;text-decoration:none;display:block;background-image:url(sprite0.png);background-position:-433px 0;}

Image Optimization in ASP.NET 5© 2010 Microsoft Corporation

Page 7: ASPNET Image Optimization

<img src="data:image/gif;base64,R0lGODlhAQABAIABAP// …

In order for the CSS classes to be accessible from a page, the CSS file itself must be attached to the page’s head section, using the typical link element:

<link href="sprites.css" rel="stylesheet" type="text/css" media="all" />

In the body of the page, you can display individual images by referencing the appropriate class in any HTML element (not just img elements):

<p class="dotNet-png" /> <br /><p class="mesh-png" /> <br />

The elements in this example will result in the following output:

Image Inlining Using Base-64 Encoding

Another performance optimization technique for images is image inlining. In this technique, you embed image data (using base-64 encoding) directly into HTML or CSS markup instead of referencing it as an external resource, as shown in Figure 5. By embedding images into HTML or CSS markup, you can reduce the number of extra HTTP requests for a page’s images to zero (or to one, depending on whether the image data is within a page’s HTML or in a linked CSS style sheet). For any given page, the browser downloads the data (the page plus the images), but with embedded images, the entire content can take as little as one download.

Figure 5: images can be encoded directly into markup.

Image Optimization in ASP.NET 6© 2010 Microsoft Corporation

Page 8: ASPNET Image Optimization

Disadvantages of Inlines Images

Although embedding image data directly into HTML reduces the number of extra HTTP requests to zero, it has some disadvantages:

Browser support. Image inlining is not supported by several popular browsers, including Internet Explorer 8 and earlier versions, and Firefox versions lower than 3.5.

Larger image sizes. When an image is converted to base-64 encoding, its size is increased, up to about 40% larger than the original size.

Duplication. Images that are repeated across several pages (such as those for interfaces) will be stored once per page instance, rather than in a single location on disk. This can cause storage bloat and makes updating these images almost impossible.

Caching. Web browsers do not cache base-64 encoded images If they are encoded directly into HTML. (However they will cache them if the images are stored in a CSS style sheet.)

You can work around all of these limitations except browser support. To offset the expansion factor of using base-64 encoding for images, you can use server-side gzip compression.

To avoid duplication and to enable caching, you can store the encoded images in CSS files (in groups, just as with sprites). The following example shows the CSS class definition for an inlined image that is similar to that of a sprite, differing only in the lack of a background-position property and the URL used for the background setting:

.dotNet-png{ width:310px; height:155px; text-decoration:none; display:block; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATYAAACb…}

Images inlined through CSS are referenced by associating a class name with an HTML element, in the same way that you reference images from a sprite collection.

Comparison of Sprites and Inlining

The following table summarizes the differences between the two methods of optimizing images and of using an img element.

img Elements Sprites Base-64 Inlining

High number of HTTP requests (one for each image)

Moderate number of HTTP requests (one for a CSS file, and one for each sprite)

Low number of HTTP requests (one for a CSS file)

Moderate file size Small file size; images save space when packed together

Larger file size due to base-64 encoding

Image Optimization in ASP.NET 7© 2010 Microsoft Corporation

Page 9: ASPNET Image Optimization

Compatible with all browsers Compatible with all current-generation browsers

Only compatible with latest versions of WebKit and Mozilla browsers

Browser Compatibility

When to Use Image Optimization Techniques

Sprites and image inlining optimizations are particularly useful when a page contains many small images that are primarily used as interface elements and decorative elements ("chrome"). However, image optimization is not suitable for all images. In general, it is not efficient to use sprites or image inlining for large content images; that is, for large images that represent content (not just decorative elements) and that appear on only a single page. For these images, optimization isn’t suitable for the following reasons:

Fewer performance gains. The large size of content images reduces the ratio of time spent downloading an image versus the time wasted on HTTP request latency. Therefore, these optimizations will not significantly increase the performance of a site if used for content images.

SEO and discoverability. Images referenced through CSS are interpreted to be background elements by web browsers and search engines. Therefore, sprites and inlined images are ignored by web crawlers.

Poor accessibility. If a page containing optimized images is read through a screen reader or displayed in a browser’s accessibility mode (which typically disables CSS), the images will not appear. In addition, the open space that would normally be reserved for a missing image will not appear, which could possibly break the page’s formatting.

No alternative (alt) text. Because inline and sprite images are background images, they do not support alternative text. This affects accessibility (see previous point) and does not let you add text that in some browsers is displayed as a tooltip.

Optimizing Images in ASP.NET

To use sprites in ASP.NET Web Forms pages, you can use the new SpriteImage control. The SpriteImage control works like the Web Forms Image control, but fully automates the task of displaying optimized images on an ASP.NET Web Forms page. Alternatively, you can use the sprites created by ASP.NET in

Image Optimization in ASP.NET 8© 2010 Microsoft Corporation

Support CSS Inlining and Sprites

FireFox >= 3.5 Safari Chrome

Support Sprites Only

Firefox < 3.5 IE 8

Only Support Standard Images

IE <= 7

Page 10: ASPNET Image Optimization

standard HTML img elements, either by using the ImageSprite.Image helper for MVC and CSHTML (Razor) pages or by manually referencing CSS descriptors that are generated by ASP.NET.

Installing and Configuring the ASP.NET Image Optimization Framework

In order to add the sprite control functionality to your site, your site must add the provided DLL files to your project and reference the ImageOptimizationFramework assembly. Web Forms sites must also reference the WebFormsControl assembly in order to get the SpriteImage control. MVC and Razor sites must also reference the MvcHelper assembly in order to have access to the ImageSprite.Image helper. Figure 6 illustrates this.

Figure 6: Assemblies required in order to use the ASP.NET image optimization framework.

The ImageOptimizationFramework assembly includes a module that must be run once at application start. To enable this module, add the following element to the Web.config file:

IIS 6

<httpModules> <add type ="Microsoft.Samples.Web.ImageOptimizationModule" name ="Microsoft.Samples.Web.ImageOptimizationModule"/></httpModules>

IIS 7

<system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add type="Microsoft.Samples.Web.ImageOptimizationModule"

name ="Microsoft.Samples.Web.ImageOptimizationModule"/> </modules></system.webServer>

Preparing Images for Optimization

To use sprites, you add images to your website in a specified location. You can optionally configure settings for the sprite by using an XML file.

Image Optimization in ASP.NET 9© 2010 Microsoft Corporation

All ProjectsImageOptimizationFramework

MVC ProjectsMvcHelper

Web Forms ProjectsWebFormsControl

Page 11: ASPNET Image Optimization

Adding Images to the App_Sprites Folder

All source images must be in a folder named App_Sprites below the site root. This folder can include subfolders, as shown in Figure 7.

Figure 7: Images for sprites must be in the App_Sprites folder under the website root.

At run time, the images in each subfolder are automatically merged into sprites or inlined directly into CSS files (which are created by the optimization package), depending on how you have configured them. (See the next section for more details on how to configure settings).

Configuring Optimization Settings

You can override the application’s default output settings by creating a settngs.xml file. You can create this file in the App_Sprites folder or individually for each subfolder that contains sprite images. If a subfolder does not contain a settings.xml file, it inherits settings from the settings.xml file (if any) in its parent folder (or uses the default settings if none can be found).

In the settings.xml file, you can create the following elements:

FileFormat. This controls the image format of the final sprite. Options are JPG, GIF, PNG, and BMP.

Quality. This controls the level of compression performed during the creation of the sprite for image formats that support this parameter. The value is specified as an integer that represents compression percentage.

MaxSize. This determines the maximum size (in KB) for sprite images. If the combined size of the images in a sprite folder exceeds this value, multiple sprites will be created automatically and referenced transparently through a single CSS file.

BackgroundColor. This defines the background color of the sprite image (including transparency), specified in standard ARGB format. This setting is typically used when you add

Image Optimization in ASP.NET 10© 2010 Microsoft Corporation

Page 12: ASPNET Image Optimization

transparent PNG images to a sprite that will be saved in a format that does not support transparency.

Base64Encoding. This enables or disables base-64 format for inlined images. (Even if this is enabled, sprites will be produced for compatibility with browsers that do not support inlined images.)

The following example shows the contents of a settings.xml file that reflects the default settings.

<?xml version="1.0" encoding="utf-8"?><ImageOptimizationSettings> <FileFormat>png</FileFormat> <Base64Encoding>true</Base64Encoding> <Quality>80</Quality> <BackgroundColor>00000000</BackgroundColor> <MaxSize>500</MaxSize></ImageOptimizationSettings>

Note the following:

The Quality element is redundant in this example, because it is ignored when the PNG output format is selected.

If you specify an output format that isn't recognized, PNG is used. The BackgroundColor value is ignored for base-64 encoded images.

How ASP.NET Image Optimization Works

This section provides details on how the image optimization framework manages and renders images in ASP.NET Web pages.

Monitoring App_Sprites for Changes

The ImageOptimizationModule module runs during the start-up phase of an ASP.NET application and implements the image optimization framework. It adds cache dependencies to the App_Sprites folder and to all of its subfolders (if any). If the contents of any of the folders changes, the optimization framework does the following:

If an image or settings file is added, removed, or modified, the directory is rebuilt, which creates a new image and .css files. If the folder’s subdirectories do not have a settings.xml file, they will be rebuilt as well, because their inherited settings may have changed.

If a directory is added, a cache item is added for it. If a directory is removed, it is not re-added to the cache (in effect, it is purged from the cache).

In addition, a file named timestamp.dat is used to check whether the directory needs to be rebuilt when the application starts. If this file had not changed, when ASP.NET restarts the application, it does not have to rebuild the entire App_Sprites directory, which can be quite processor and I/O intensive.

Image Optimization in ASP.NET 11© 2010 Microsoft Corporation

Page 13: ASPNET Image Optimization

How Images Are Displayed by the Built-In Controls

Sprite and inlined images are rendered using CSS IDs or classes, which you can associate with HTML elements such as div, span, a, p, and img. Because you want optimized images to be treated as images with respect to CSS, the Web Forms control and MVC helper functions render these images using img elements whose src attribute is set to a 1x1-pixel transparent GIF image (encoded directly into the src attribute), and then use CSS classes to display the appropriate image. The following example shows typical markup that is rendered by the SpriteImage control:

<img class="aspNetLogos_2-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />

To ensure compatibility across all browsers, the image optimization framework generates two CSS files: highCompat.css, which allows the use of inlined images (if you enabled this option), and lowCompat.css, which will only render sprites.

In order for the CSS reference to work correctly, the correct style sheet must be linked in the page’s head section. The following example shows a link to the style sheet that is compatible with all browsers (that is, that renders using sprites):

<link href="App_Sprites/aspNetLogos/lowCompat.css" rel="stylesheet" type="text/css" media="all" />

Adding Optimized Images to a Page

The approach you use for taking advantage of optimized images in a page depends on whether you are using a Web Forms page or an MVC view or Razor page, or whether it makes sense for you to create images in the markup manually.

ASP.NET Web Forms Control

To use optimized images in an ASP.NET Web Forms page, add the SpriteImage control, using syntax like in the following example:

<SpriteImage:SpriteImage ID="SpriteImage3" runat="server" ImageUrl="~/App_Sprites/aspNetLogos/2.png" Optimize="true" />

You set the ImageUrl property to the unoptimized source image in the App_Sprites folder that you want the control to display, and set the additional Optimize property to true. When the page is rendered, the image optimization framework adds the appropriate CSS link to the page’s header, and renders an img element whose class attribute that points to the appropriate CSS definition for the optimized image.

Image Optimization in ASP.NET 12© 2010 Microsoft Corporation

Page 14: ASPNET Image Optimization

ASP.NET MVC and Razor Helper

To use image optimization in an MVC or Razor page, you must add two helpers, one to render the link to the CSS file in the view or page, and the other to render the image in the page. To render the CSS link, add the following helper inside the head element:

<%: Microsoft.Samples.Web.ImageSprite.ImportStylesheet("~/App_Sprites/myImage.jpg") %>

The ImageSprite.ImportStylesheet method generates the HTML markup required to link the proper CSS file (based on browser compatibility) to a page’s header. For MVC applications, you must pass this through to the head element, typically by using a ContentPlaceHolder element.

To insert images into a view or Razor page, use the ImageSprite.Image helper as in the following example:

<%: Microsoft.Samples.Web.ImageSprite.Image("~/App_Sprites/myImage.jpg") %>

Raw HTML Markup

You can also manually add sprites and inlined images created by the optimization framework into any HTML page. In order for the images to be correctly referenced, you must link the correct style sheet to the page’s head section, as in the following example:

<link href="App_Sprites/subFolderOne/subFolderTwo/lowCompat.css" rel="stylesheet" type="text/css" media="all" />

If your site will be visited by users who might use different browsers, it is recommended that you link to the low-compatibility CSS file (which enables sprites, but not inlining), because most web browsers do not display inlined images. If you can safely predict that your users will have browsers that support inlined images, you can link to the alternative CSS file.

You can then reference an optimized image through a CSS class, using a class name that is generated based on the path of the source image file relative to the App_Sprites folder. Because the “/” and “.” characters are reserved in CSS definitions, they are converted into “_“ and “-“, respectively, when the class names are generated by the framework. For example, an image might be stored at the following path:

~/App_Sprites/subFolderOne/subFolderTwo/myImage.png

The generated CSS class name would be the following:

subFolderOne_subFolderTwo_myImage-png

You can associate the class with a variety of HTML elements, including the inlined one-pixel transparent GIF discussed earlier, using syntax like the following:

<img class="subFolderOne_subFolderTwo_myImage-png"

Image Optimization in ASP.NET 13© 2010 Microsoft Corporation

Page 15: ASPNET Image Optimization

src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />

Manually referencing the CSS class is useful if you do not want to use the SpriteImage server control or the ImageSprite.Image helper. The optimization framework still automates the tasks of merging images and generating CSS, and produces a consistent class name that you can use to access the images. Creating the markup manually is particularly useful if you use sprites in navigation elements that use JavaScript or in elements that include rollover behaviour, because you normally do not use an img element in these scenarios.

Image Optimization Quick Reference

The ImageOptimizationFramework class includes public members that you can use to integrate its features into your code.

Static Fields

HighCompatibilityCssFile The name of the CSS file used for browsers that are able to use inlined images.

LowCompatibilityCssFile The name of the CSS file used for browsers that do not support inlining.

InlinedTransparentGif The base-64 encoded string for a single-pixel inlined GIF image.

SettingsFileName The name of the file used to override a directory’s image optimization settings.

TimestampFileName The name of the file used to check if a directory needs to be rebuilt on application start.

Public Methods

AddCacheDependencies Adds cache items to the specified directory and all of its subdirectories.

IsOutputSprite Returns true if the path parameter points to a sprite file produced by the framework or to a CSS file.

LinkCompatibleCssFile Returns the name of the CSS file that the current browser is able to support, or null if the browser cannot support any optimizations.

MakeCssClassName Generates the CSS class name used by the framework to reference an optimized image. The path parameter must be a subdirectory of App_Sprites.

RunAtDirectory Runs the optimization process on a specified directory. The checkIfFilesWereModified parameter specifies whether the directory should be rebuilt even if the files have not been modified since the last build.

Image Optimization in ASP.NET 14© 2010 Microsoft Corporation

Page 16: ASPNET Image Optimization

Disclaimer

This is a preliminary document and may be changed substantially prior to final commercial release of the software described herein.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.

Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, email address, logo, person, place or event is intended or should be inferred.

© 2010 Microsoft Corporation. All rights reserved.

Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Image Optimization in ASP.NET 15© 2010 Microsoft Corporation