Documente Academic
Documente Profesional
Documente Cultură
Microsoft Corporation
Table of Contents
Introduction ......................................................................................................................................2 The Performance Penalty of HTTP Requests ............................................................................................ 2 Reducing the Number of HTTP Requests .............................................................................................3 Sprites ....................................................................................................................................................... 3
How Sprites Work .................................................................................................................................................4
Comparison of Sprites and Inlining .....................................................................................................2 Browser Compatibility............................................................................................................................... 2 When to Use Image Optimization Techniques .....................................................................................2 Optimizing Images in ASP.NET ............................................................................................................3 Installing and Configuring the ASP.NET Image Optimization Framework ..............................................3 Preparing Images for Optimization .....................................................................................................4 Adding Images to the App_Sprites Directory ............................................................................................ 4
Changing the location of the sprites directory ......................................................................................................5 Granting the ASP.NET worker process write permissions to the sprites directory ................................................5
Configuring Optimization Settings ............................................................................................................ 5 How ASP.NET Image Optimization Works ...........................................................................................6 Monitoring the App_Sprites Directory for Changes ................................................................................. 6 How Images Are Displayed by the Built-In Controls ................................................................................. 7 Adding Optimized Images to a Page ....................................................................................................7 ASP.NET 4 Web Forms Projects ................................................................................................................ 8 ASP.NET MVC 3 and ASP.NET Web Pages (Razor) Projects ...................................................................... 8
Using image optimization in .aspx views ..............................................................................................................9 Using image optimization in Razor pages.............................................................................................................9
Manually Using Optimized Images in HTML Markup................................................................................ 9 Image Optimization Quick Reference ................................................................................................ 11 Static Fields ............................................................................................................................................. 11 Public Methods ....................................................................................................................................... 11 Disclaimer........................................................................................................................................ 12
Introduction
The ASP.NET image performance optimization framework is designed to decrease the amount of time thats required in order to request and display a page from a web server by performing a variety of optimizations on the pages images.
Figure 1: Pages on the Northwind Online site include a large number of small images. Without image optimization, these images would cause a page to load slowly as the browser requests each image individually.
Most browsers and web servers are configured to allow anywhere between two and six HTTP connections at a time. This resulting HTTP request latency can 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.
Small interface images much of the time it takes to download each is simply due to latency
Figure 2: A partial analysis of the time spent loading a popular technology news site. The Xaxis 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 latency time required in order to initiate each download, while the smaller dark purple segments indicate the actual download time. Additionally, there's 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 providers server and network, because the reduced number of HTTP requests lessens the work for load balancers.
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 games
individual bitmaps into a single grid-style file, they could significantly reduce the amount of memory required in order 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 a 1980s 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 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 .css file that's also required). 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 backgroundimage 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 different dimensions for background-position, width, and height settings.
.azureLogo\.png { width:123px; height:115px; background-image:url(sprite0.png); background-position:0px 0px; } .dotNet\.png { width:310px; height:155px; background-image:url(sprite0.png); background-position:-123px 0px; } .exchange\.png { width:119px; height:138px; background-image:url(sprite0.png); background-position:-433px 0px; }
.mesh\.png { width:307px; height:312px; background-image:url(sprite0.png); background-position:-552px 0px; } .windowsLogo\.png { width:245px; height:210px; background-image:url(sprite0.png); background-position:-859px 0px; } .xbox\.png { width:208px; height:207px; background-image:url(sprite0.png); background-position:-1104px 0px; }
In order for the CSS classes to be accessible from a page, the CSS file itself must be referenced in the pages <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 number of extra HTTP requests for a pages images to zero (or to one, depending on whether the image data is in a pages 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 require as little as one download.
<img src="data:image/gif;base64,R0lGODlhAQABAIABAP//
Disadvantages of Inlined 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 isn't supported by Internet Explorer 7 and earlier versions. 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 are stored once per page instance rather than in a single location on disk. This can cause storage bloat. Caching. Web browsers don't cache base-64 encoded images if they're encoded directly into HTML. (However they'll cache them if the images are stored in a CSS style sheet.)
You can work around all of these limitations except browser support. For example, 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's 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; 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.
Small image file size; images save Larger page size due to base-64 space when packed together encoding Compatible with all browsers Compatible with all currentgeneration browsers Only compatible with latest versions of WebKit, Mozilla browsers, Internet Explorer (IE8+)
Browser Compatibility
The following table shows which browsers support which optimization options.
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 browsers accessibility mode (which typically disables CSS), the images won't appear. In addition, the open space that would normally be reserved for a missing image won't appear, which could possibly break the pages formatting. If Windows is running in high contrast mode the sprite images will not display. No alternative (alt) text. Because inline and sprite images are background images, they don't support alternative text. This affects accessibility (see previous point) and doesn't let you add text that screen readers would read.
Figure 6: Assemblies required for using the ASP.NET image optimization framework.
The Microsoft.Web.Samples.ImageOptimizationFramework assembly includes a module that must be run once at application start. The module is registered dynamically for ASP.NET MVC 3 projects and ASP.NET Web Pages (Razor) sites, and no Web.config changes are required. For Web Forms projects, you must enable the module in the Web.config file as shown in the following examples:
IIS 6
<httpModules> <add type="Microsoft.Web.Samples.ImageOptimizationModule" name="Microsoft.Web.Samples.ImageOptimizationModule"/> </httpModules>
Figure 7: Images for sprites must be in the App_Sprites directory under the website root.
At run time, the images in each subdirectory are automatically merged into sprites or inlined directly into CSS files (which are created by the optimization package), depending on how you've configured them. (See the next section for more details on how to configure settings.) Changing the location of the sprites directory If it isn't practical to use the App_Sprites directory, it is still possible to use the image optimization framework by changing its root directory, which is assigned in the ImageOptimizations class. To modify the path of the root sprite directory, open the ImageOptimizations.cs file in the image optimization framework project that's included in the framework download. Edit the SpriteDirectoryRelativePath constant so that it points to the path that you want to use, save the file, and then recompile the project. Granting the ASP.NET worker process write permissions to the sprites directory If your site is running under IIS, the ASP.NET worker process account must have write permissions to the sprites directory so that it can save the generated sprite image file.
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. The default is 80. MaxSize. This determines the maximum size (in KB) for sprite images. If the combined size of the images in a sprite directory exceeds this value, multiple sprites will be created automatically and referenced transparently through a single CSS file. The default is 450. 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 transparent PNG images to a sprite that will be saved in a format that doesn't support transparency. The default is that the background color is transparent. 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 don't support inlined images. The default is true. TileInYAxis. When this element is set to true, sprites will tile images along the y-axis rather than the x-axis. If your images have the same height but different widths, the size of the generated sprite might be smaller if you tile along the x-axis. Similarly, if your images have the same width but different heights, tiling along the y-axis might result in a smaller sprite image. The default is false, which means sprites will tile along the x-axis
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.
If an image or settings file is added, removed, or modified, the directory is rebuilt, which creates a new image and new .css files. If the sprite directory has subdirectories that contain a settings.xml file, they'll 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 isn't re-added to the cache (in effect, it is purged from the cache). The contents of CSS files within a directory that were not generated by the framework are copied into the generated CSS.
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 has not changed, when ASP.NET restarts the application, it doesn't have to rebuild the entire App_Sprites directory, which can be very processor and I/O intensive.
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. Folders and filenames can contain any Unicode characters. The only exception to this rule is the space character. This character will be converted be converted to a hyphen (-) in order to create a valid CSS selector. This could potentially lead to a name collision if you have two files that differ by only a space and a hyphen. For example, two files named my file.png and my-file.png would conflict. In order for the CSS reference to work correctly, the correct style sheet must be linked in the pages <head> section. The following example shows a link to the style sheet that's compatible with all browsers (that is, that renders using sprites):
<link href="App_Sprites/aspNetLogos/lowCompat.css" rel="stylesheet" type="text/css" media="all" />
Alternatively, you can register the tag for the entire site by adding the following element to the sites Web.config file:
<pages> <controls> <add tagPrefix="asp" namespace="Microsoft.Web.Samples" assembly="Microsoft.Web.Samples.ImageSprite" /> </controls> </pages>
You set the ImageUrl property to the unoptimized source image in the App_Sprites directory that you want the control to display. When the page is rendered, the image optimization framework adds the appropriate CSS link to the pages header, and then renders an <img> element whose class attribute points to the appropriate CSS definition for the optimized image. If you want to link only the appropriate CSS file to a page without displaying an image, use the ImageSpriteCssLink control instead, as in the following example:
<asp:ImageSpriteCssLink runat="server" ImageUrl="~/App_Sprites/categories" />
This code adds a reference to the appropriate generated CSS sprite file to the page.
If youre using Razor views, the namespace is automatically added. No additional configuration is required. If you dont want to add the namespace reference globally, you can reference it in individual pages (views). After the namespace references have been added, you need to render the link to the CSS file. The Sprite.ImportStylesheet method generates the HTML markup that's required in order to link the proper CSS file (based on browser compatibility) to a pages header. Using image optimization in .aspx views If you haven't already added a global reference to the Microsoft.Web.Samples namespace, you can add a reference in an .aspx view page using the following Import directive:
<%@ Import Namespace="Microsoft.Web.Samples" %>
To render the CSS link in an .aspx view page, add the following helper inside the HTML <head> element:
<%: Sprite.ImportStylesheet("~/App_Sprites/") %>
To insert images into an .aspx view page, use the Sprite helper as in the following example:
<%: Sprite.Image("~/App_Sprites/myImage.jpg") %>
The method Image also supports a second parameter in order to add more attributes to the rendered image tag:
<%: Sprite.Image("~/App_Sprites/myImage.jpg", new { alt = "Specific Alt Text" }) %>
Using image optimization in Razor pages For a Razor view page, use the following syntax to generate the markup for the CSS file:
@Sprite.ImportStylesheet("~/App_Sprites/")
The method Image also supports a second parameter in order to add more attributes to the rendered image tag:
@Sprite.Image("~/App_Sprites/myImage.jpg", new { alt = "Specific Alt Text" })
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 don't 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's generated based on the path of the source image file relative to the App_Sprites directory. Because the space character is reserved in CSS definition, it is converted to a hyphen (-) when the class names are generated by the framework. For example, an image might be stored at the following path: ~/App_Sprites/subDirectoryOne/subDirectoryTwo/myImage.png The generated CSS class name would be the following: subDirectoryOne/subDirectoryTwo/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="subDirectoryOne/subDirectoryTwo/myImage.png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw ==" />
Manually referencing the CSS class is useful if you don't want to use the ImageSprite control or Sprite helper. The optimization framework still automates the tasks of merging images and generating CSS, and it 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 don't use an <img> element in these scenarios. However, it is recommended that you use the method to generate the class name automatically. This would avoid problems if special characters are present in the filename. The syntax is:
<img class="<%= ImageOptimizations.MakeCssClassName("~/App_Sprites/subDirectoryOne/subDirectoryTwo/my Image.png") %>" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw ==" />
Static Fields
HighCompatibilityCssFile LowCompatibilityCssFile InlinedTransparentGif SettingsFileName TimestampFileName The name of the CSS file used for browsers that can use inlined images. The name of the CSS file used for browsers that don't support inlining. The base-64 encoded string for a single-pixel inlined GIF image. The name of the file used to override a directorys image optimization settings. The name of the file used to check whether a directory needs to be rebuilt on application start.
Public Methods
AddCacheDependencies IsOutputSprite LinkCompatibleCssFile MakeCssClassName Adds cache items to the specified directory and all of its subdirectories. Returns true if the path parameter points to a sprite file produced by the framework or to a CSS file. Returns the name of the CSS file that the current browser is able to support, or null if the browser can't support any optimizations. Generates the CSS class name used by the framework to reference an optimized image. The path parameter must be a subdirectory of App_Sprites. Runs the optimization process on a specified directory. The checkIfFilesWereModified parameter specifies whether the directory should be rebuilt even if the files haven't been modified since the last build.
ProcessDirectory
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. 2011 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.