Click here to Skip to main content
15,860,859 members
Articles / Web Development / ASP.NET
Article

HTTP Compression Module

Rate me:
Please Sign up or sign in to vote.
4.81/5 (39 votes)
19 Mar 2008CPOL6 min read 363.4K   4.8K   153   119
A compression module for ASP.NET that works with WebResource.axd, JavaScript, and CSS

Introduction

Compressing files before they are sent to the browser has many benefits. The page will load faster and less bandwidth is used, resulting in better user experience and reduced cost. There are a few different HTTP Compression module implementations out there, but I wanted one that would compress WebResource.axd. I couldn't find any that did, so I tried to find a way to do it myself.

This implementation has three parts to it. One is the compression of Web pages. For this I used the Flanders implementation found here, or on The Code Project here. I started with Ben Lowery's code, but Flanders code was much leaner, cleaner, and specific to .NET 2.0. It has been modified to use a custom filter to replace JavaScript and stylesheet links.

Next is combining multiple JavaScript and CSS files into one file and compressing them. The technique is described here. To summarize the article, it is better to have one JavaScript file and one CSS file for the browser to download. This is because the browser can't use parallel downloading for these types of files. Each one must be downloaded before another can begin. But it is also difficult to maintain large JavaScript and CSS files. The solution is to keep them separate, and then combine them into one file dynamically. And then on top of that, compress them. I've changed the way this is done a little, but I think it is slightly better. I have updated the HttpModule to parse through the HTML of the page and replace the links to JavaScript and CSS files, combining wherever possible. It is now possible to write your pages like you normally would (in the past, to compress a script you would have to link to js.axd?files=jsfiletocompress.js) and the HttpModule will replace the link with an appropriate js.axd?files=jsfiletocompress or css.axd?files=csstocompress.css. So the page will work with or without the compression enabled. This makes it a lot easier and allows us to take advantage of Visual Studio 2008's designer.

Imagine, instead of including five JavaScript files equaling 177 KB, you can include one file equaling 52 KB. For example, in the sample Web site, there are 5 JavaScript files: 2 ScriptResource.axd, 2 WebResource.axd, and 1 *.js file that combines 5 *.js files in the JavaScript folder. Uncompressed, these files would equal 329 KB, but compressed they equal 89 KB. Those are huge savings.

The third is the compression of WebResource.axd. I will give a quick explanation of the Web resource compression. A call to WebResource.axd using the compression module breaks it for some reason. I tried, to no avail, a lot of different ways to get around this problem. I am able to compress the WebResource.axd by replacing any JavaScript or CSS links with something that looks like this: js.axd?files=WebResource.axd?d=sldkf09sdf098&t=9896987987. Then when the HttpHandler runs, it checks to see if the file is a local file, if not then it downloads it. All files are cached on the server and on the browser (including WebResource.axd). This way also enables you to include JavaScript or CSS from another domain and still compress and cache the files.

There are a couple of changes that I made to the original Flanders HttpCompression module. First and foremost is instead of having the code being all inclusive, I changed it to be all exclusive. Meaning, instead of having a long list of excluded mime types that you want to exclude, I have included mime types and included path section in the Web config. So, most likely you will only want files of mime type text/html to be compressed with the module (this won't affect the JavaScript, CSS, or WebResource.axd from being compressed). I did leave the excluded mime type and paths intact allowing for exclusion of items that have been included. Also, I added the ability to use '*' to include all mime types (this makes it work like the original implementation and you must exclude all types you don't want compressed).

I might mention that if you are running a page from Visual Studio 2005's development server, all mime types will go through the compression module, but if you run it from IIS, they will not. Images, JS, and CSS files, and static pages do not go through the ASP.NET pipeline but are served up directly.

I also added code to make it work with update panels. This is done by adding...

C#
if (app.Request["HTTP_X_MICROSOFTAJAX"] != null)
    return;

... to the beginning of the context_PostReleaseRequestState method.

I do not claim to be a C# guru, and as such, there may be better ways to do what I am doing. I welcome any comments or suggestions to make this code better. This code should be considered beta software. Also, there are many improvements and features that may be added, but I don't have time to do so. I have been successful in using this code at the University where I work, which uses load balanced servers running IIS6, and on my personal Website running in a medium trust environment (hosted by GoDaddy). I cannot, however, guarantee that it will work for you.

This project was written using Visual Studio 2005 and C# 2.0 and is not meant to run in a .NET 1.1 environment.

Using the Code

Add a reference to the DLL or drag and drop the DLL into the bin folder of the Web application. Add the following to the web.config. That's it! It should work transparently, meaning you can develop your site without the compression module, then add the compression later; or develop with the compression module and then remove it later without having to make any changes besides deleting the web.config items and the DLL.

Web.config

The only settings that have been added is the use of the <IncludedMimeTypes>, <IncludedPaths> (IncludedPaths has not been fully tested), <CacheSettings>, and <PathSettings>.

<IncludedMimeTypes> is described above and tells the module what mime types to compress. Again, you may use '*' to compress all mime types that may pass through the module. <CacheSettings> is for the caching of the JavaScript and CSS files (including WebResource.axd). <PathSettings> is where the JavaScript and CSS files are located. I will talk more about this later. Defaults are: cacheFiles=false, path=cache, jsPath=javascript, and cssPath=css.

ASP.NET
<configSections>
  <sectionGroup name="DCWeb">
    <section name="HttpCompress" type="DC.Web.HttpCompress.Configuration,
        DC.Web.HttpCompress"/>
  </sectionGroup>
</configSections>

<DCWeb>
  <HttpCompress  compressionType="GZip">
    <IncludedMimeTypes>
      <add mime="text/html" />

    </IncludedMimeTypes>
    <!--<ExcludedMimeTypes>
      <add mime="text/html" />
    </ExcludedMimeTypes>-->
      <ExcludedPaths>

        <add path="~/NoCompress/Default.aspx" />
      </ExcludedPaths>
    </HttpCompress>
</DCWeb>

<!-- The js.axd and css.axd must be enabled to allow javascript and css
    compression -->
<httpHandlers>
  <add verb="*" path="js.axd,css.axd"
      type="DC.Web.HttpCompress.CompressionHandler,DC.Web.HttpCompress"/>
</httpHandlers>
<!-- The compression module must be enabled for the WebResource.axd to be
     compressed -->
<httpModules>
  <add name="HttpCompressModule"
      type="DC.Web.HttpCompress.HttpModule,DC.Web.HttpCompress"/>
</httpModules>

Including JavaScript and CSS

This has changed since the previous version. Just include the JavaScript and CSS like you normally would. You can even use stylesheet themes, this is demonstrated in the included solution.

Caching the Files

The files are cached under the context.Cache on the server and on the browser using Etags.

Conclusion

It's that easy to enable compression of Web pages, JavaScript, CSS, and the WebResource.axd. I hope you find this code as useful as I have.

History

  • 03/18/2008 - Article, source code and demo updated
  • 02/06/2008 - Major update to the code. Changed to use a custom filter to replace JavaScript includes and CSS links with ones pointing to a HttpHandler. Changed the HttpHandler to cache differently on the server and to compress the output differently.
  • 05/17/2007 - Updated code which caused CSS errors
  • 04/30/2007 - Created article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
General2 major issues to note Pin
_Stilgar_18-Sep-08 6:30
_Stilgar_18-Sep-08 6:30 
GeneralRe: 2 major issues to note Pin
not_ginger_matt4-Sep-10 7:17
not_ginger_matt4-Sep-10 7:17 
GeneralUnGZip Failed in Fiddler [modified] Pin
Matthew Marksbury9-Sep-08 9:51
Matthew Marksbury9-Sep-08 9:51 
Questionhow I can apply compression with help your library to html and javascript file when they are hosted in IIs Pin
vivek shivalkar2-Sep-08 2:53
vivek shivalkar2-Sep-08 2:53 
AnswerRe: how I can apply compression with help your library to html and javascript file when they are hosted in IIs Pin
darick_c9-Sep-08 10:18
darick_c9-Sep-08 10:18 
GeneralRe: how I can apply compression with help your library to html and javascript file when they are hosted in IIs Pin
babak ravandi8-Dec-09 12:34
babak ravandi8-Dec-09 12:34 
Generalpost a small bug Pin
leegool28-Aug-08 23:26
leegool28-Aug-08 23:26 
GeneralRe: post a small bug Pin
stormydaniels19-Nov-08 10:08
stormydaniels19-Nov-08 10:08 
Self closed script tags are invalid. Just run your page through the w3c validator.
GeneralRe: post a small bug Pin
jfsanchez2k14-Mar-09 5:22
jfsanchez2k14-Mar-09 5:22 
QuestionGetting error in MyMin.cs Pin
anjon5-Aug-08 19:31
anjon5-Aug-08 19:31 
GeneralCss 'media' attribute problen Pin
Mironcito24-Jul-08 17:51
Mironcito24-Jul-08 17:51 
General&lt;excludedpaths&gt not working Pin
mombuto20-Jul-08 5:10
mombuto20-Jul-08 5:10 
GeneralUmm... Critique? :) Pin
Artiom Chilaru6-Jul-08 8:40
Artiom Chilaru6-Jul-08 8:40 
QuestionGetting error in MYMIN.cs Pin
Member 27175042-Jul-08 12:00
Member 27175042-Jul-08 12:00 
QuestionRe: Getting error in MYMIN.cs Pin
darick_c2-Jul-08 12:59
darick_c2-Jul-08 12:59 
GeneralHTTP Compression Pin
AndriyZZ2-Jul-08 5:53
AndriyZZ2-Jul-08 5:53 
GeneralRe: HTTP Compression Pin
darick_c2-Jul-08 12:58
darick_c2-Jul-08 12:58 
NewsHTTP compression Pin
AndriyZZ2-Jul-08 5:37
AndriyZZ2-Jul-08 5:37 
Generalviewstate compression,, Pin
shaunie2fly1-Jul-08 13:08
shaunie2fly1-Jul-08 13:08 
GeneralRe: viewstate compression,, Pin
darick_c1-Jul-08 17:11
darick_c1-Jul-08 17:11 
Generalfavicon problem Pin
shaunie2fly1-Jul-08 12:16
shaunie2fly1-Jul-08 12:16 
GeneralRe: favicon problem Pin
darick_c1-Jul-08 12:35
darick_c1-Jul-08 12:35 
GeneralRe: favicon problem Pin
shaunie2fly1-Jul-08 13:23
shaunie2fly1-Jul-08 13:23 
QuestionWhat about HTTP request compression? Pin
AndriyZZ25-Jun-08 12:35
AndriyZZ25-Jun-08 12:35 
GeneralScriptResource.axd Pin
mombuto22-Jun-08 5:13
mombuto22-Jun-08 5:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.