If you care about your website performance, I’m sure you must know about the YSlow addin for Firebug.

One of its recommendations is to add an Expires header with a far future expiration date for your static content. You can read more about it here.

image

If you use CSS for your layout (which you should) you are probably using CSS background images as well. These images should very rarely change, so you could just make sure your entire /images/ directory is served with an appropriate cache expiration header.

If you’re using IIS7, all you need to do is create a web.config in your /images/ folder which contains something like the following:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
            <clientCache cacheControlMode="UseExpires" httpExpires="Sun, 01 Dec 2019 00:00:00 GMT" cacheControlCustom="" />
        </staticContent>
    </system.webServer>
</configuration>

Now the client’s browser can cache your images until 2019, and your YSlow score should be dramatically improved.

But what happens when you need to change an image? All your returning visitors would have to clear their cache to see the updated version, so that’s something we’re trying to avoid.

Enter T4 Templates

To work around this, you can use a feature of IIS and request the static images and including a querystring. For example: /images/bg.png?something works the same as /images/bg.png, but it comes with the added benefit of the user’s browser thinking they’re entirely different files, so it will cache them separately.

Armed with this knowledge, it becomes apparent that we want our .css stylesheet to link to images with a versioned querystring, which we can easily just increment when we update our images so it’s all seamless for the visitor.

Using the Text Template Transformation Toolkit (T4) readily available in Visual Studio we can create a .tt file which autogenerates our .css and takes care of your versioning needs.

Simply add a new file with a .tt extension to your Website Project, and paste the following into it:

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#v3.5" debug="true" hostSpecific="true" #>
<#@ output extension=".css" #>

/* example css */
body { background:url(<#= GetImage("main_bg.jpg") #>) }
/* other css */
.someclass { background:url(<#= GetImage("main_box_top_bg.jpg") #>) repeat-x top #FFF; width:960px; }

<#+
// you can simply change the value of the 'version' variable below
// to something else when you update your images

static string version = "1";

string GetImage(string image)
{

    // replace /images/ with your images directory name
    return "/images/" + image + "?" + version;
}#>

Notice the <#= GetImage(“filename.png”) #> embedded code blocks.

Now, when you Save the file in Visual Studio, if your t4 syntax is valid, you should see a generated .css file under the .tt file in Solution Explorer.

image

Here’s how the generated .css file looks like:

/* example css */
body { background:url(/images/main_bg.jpg?1) }
/* other css */
.someclass { background:url(/images/main_box_top_bg.jpg?1) repeat-x top #FFF; width:960px; }


All your layout images should be now cached, and they won’t needlessly be downloaded on every page view. Your visitors will thank you!