SharpBarb
SharpBarb

Reputation: 1590

Manually Enable Compression Using httpModule

I'm trying to enable gzip compression on a site on our work intranet. Unfortunately, I don't have access to IIS, so any changes I make have been through web.config.

The server is running IIS 6 and .NET 2.0.

I enabled compression by adding an httpmodule

public class EnableCompression : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += 
            (new EventHandler(this.Application_BeginRequest));

    }

    private void Application_BeginRequest(Object source, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
        HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
        HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;
    }

}

I registered in the web.config...

<system.web>
    <httpModules>
      <add name="EnableCompression" type="EnableCompression"/>
    </httpModules>
</system.web>

Well, the above worked fine, except javascript and css files do not get compressed. From what I have found, I would have to add .js and .css to the application mappings in IIS 6, but of course I can't do that.

Apparently this can be done via the web.config file, but I don't know how to do that.

How can I enable compression for .js and .css files?

Upvotes: 4

Views: 1378

Answers (2)

RickNZ
RickNZ

Reputation: 18654

In IIS6, static code is not processed by managed HttpModules; it requires a native ISAPI.

One trick you can use is to convert your *.js and *.css files into dynamic files. You do this by changing them to be *.aspx, and set the ContentType to the right MIME type. For example:

this.Response.ContentType = "application/x-javascript";

The only other trick is to set StyleSheetTheme="" in the Page directive in the markup file. Otherwise, the runtime will insist on a <head> section in the document. You can enable output caching to minimize the performance impact.

I wrote a blog post about this on the JS side, in case it helps (CSS is similar, just with a different MIME type): http://www.12titans.net/p/dynamic-javascript.aspx

Unfortunately, this requires changing the name of your JS and CSS files in your app, but if you want compression and don't have access to IIS, I don't think there's a way around that.

If you want to keep the *.js and *.css extensions, you can do so by adding a handler for them in your web.config. For example:

<compilation>
  <buildProviders>
    <add extension=".css" type="System.Web.Compilation.PageBuildProvider"/>
  </buildProviders>
</compilation>

<httpHandlers>
  <add path="*.css" verb="*" type="System.Web.UI.PageHandlerFactory"
       validate="true"/>
</httpHandlers>

This helps from a naming perspective, but not performance; the files will still be dynamic -- they are basically *.aspx files, but with a different extension. It also doesn't work correctly with ASP.NET Themes, since pages in the Themes folder can't be dynamic, regardless of their extension.

Upvotes: 1

bryanmac
bryanmac

Reputation: 39306

Adding to @RickNZ's answer:

Be careful about converting to dynamic. IIS is much faster at serving static files than dynamic (kernel mode). Only consider that if your app is dominated by bandwidth concerns.

One other option is to look into CDNs for static content (content delivery networks). Azure, Amazon, Akamai and others offer services. That's a very fast geo-located friendly way of serving static files.

Upvotes: 0

Related Questions