GZip compress your website's HTML/CSS/Script in code

15 May 2008 - 2:23 PM / by Dominic Pettifer. 13 Comments

Cool C# Snippets - Dynamically GZIP compress the HTML response of your website in code, without having to configure IIS directly. Make massive savings on your websites bandwidth.

Dynamic GZIP Compression in Code

I recently found a way to GZIP compress the HTML, CSS and Javascript output from an ASP.NET website, dynamically in code. GZIP compression can drastically reduce the file sizes for any text based file served to the client. This includes the raw HTML, CSS, Javascript files, even plain XML or CSV, but it can't compress images, media and binary files. Normally, you'd set this on the server, but what if you dont have access to the server.

First create a Global.asax file in your web root and put the following line in it, deleting everything thats there currently...

<%@ Application Language="C#" Inherits="Global" %>

Then create a Global.cs file in your APP_CODE folder and put the following code in...

using System;
using System.IO.Compression;

public class Global : System.Web.HttpApplication
{
    public Global()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        this.PostReleaseRequestState +=
            new EventHandler(Global_PostReleaseRequestState);
    }

    private void Global_PostReleaseRequestState(
        object sender, EventArgs e)
    {
        string contentType = Response.ContentType;

        if (contentType == "text/html" ||
            contentType == "text/css")
        {
            Response.Cache.VaryByHeaders["Accept-Encoding"] = true;

            string acceptEncoding =
                Request.Headers["Accept-Encoding"];

            if(acceptEncoding != null)
            {
                if (acceptEncoding.Contains("gzip"))
                {
                    Response.Filter = new GZipStream(
                        Response.Filter, CompressionMode.Compress);
                    Response.AppendHeader(
                        "Content-Encoding", "gzip");
                }
                else if (acceptEncoding.Contains("deflate"))
                {
                    Response.Filter = new DeflateStream(
                        Response.Filter, CompressionMode.Compress);
                    Response.AppendHeader(
                        "Content-Encoding", "deflate");
                }
            }
        }
    }
}

The browser will tell the server whether it supports GZIP or DEFLATE compression (via the Accept-Encoding header). If its an older browser that doesn't support compression, it will just be sent as uncompressed HTML and your site will still work.

The magic happens with the following lines...

Response.Filter = new GZipStream(
    Response.Filter, CompressionMode.Compress);
Response.AppendHeader("Content-Encoding", "gzip");

Response.Filter (also available from your ASPX pages) exposes a Stream which you override with a GZipStream object, this will cause the raw text response to get compressed, while telling the browser this the response is compressed with the second line Response.AppendHeader.

The reason we put this in the Global_PostReleaseRequestState event is because it allows us to target all files, not just ASPX pages.

Pay attention to the line if (contentType == "text/html" || contentType == "text/css"), I had an issue where I was using the ASP.NET AJAX extensions Control Toolkit which was supplying it's own external javascript files that were already GZIP compressed, and since it was trying to compress an already compressed file, it was screwing it up causing issues and throwing script errors on the client, because the browser couldn't read the script files. So be aware of this, if you have complete control over your external JavaScript files then could probably add the code...

|| contentType == "application/x-javascript" || contentType == "text/javascript"

...to that IF statement.

FYI, I tried adding this code to an application I was working on at Conscia. The client wouldn't let us turn GZIP compression on their own servers, and we didn't have any access to them. Page sizes were around 150-200KB but after adding this code they now sit at around 20-30KB, a massive improvement which would benefit the particular slow network this application was being made to run on.

Page loads times were quicker and the application seemed noticably more responsive. So your benefits are lowered costs and an improved user experience.

13 Comments on " Dynamic GZIP Compression "

Post a Comment

Leave a Comment

Comment Details
*
* BBCode: [b]bold[/b], [i]italics[/i], [code]code[/code], [li]bullet point[/li], [h]Heading[/h], [url="http://www.example.com"]link[/url], [quote author="John Smith"]quote[/quote]

Random Image

Bugatti Veyron - As a photo mosaic.

Bugatti Veyron - As a photo mosaic. (from the blog Photo Mosaic Generator - Fun Adventures With Silverlight )

Quick Poll

What is your DIP/IOC Container of choice?

Poll Vote
(see results)
View Comments (0) (See previous polls)

Latest Tweets

  • Red Bull gives you wings....that generate huge amounts of downforce #F1

    about 18 hours ago from Twitterrific
  • .vampire { -webkit-box-shadow: none; -webkit-box-reflection: none; } #cssjokes

    7:44 PM July 30th from Echofon
  • @edhenderson lol, lets get a trending topic going - .gangster .wrapper { color: #000; width: 150%; text-decoration: bling; } #cssjokes

    7:36 PM July 30th from Echofon
  • @weblivz I think the petition should be resubmitted but with security stuff taken out, as that's what the response purely focused on

    6:13 PM July 30th from Echofon
  • @weblivz I still think Chrome Frame can come to the rescue here, still keep their old browsers + legacy systems, no retraining costs etc.

    6:12 PM July 30th from Echofon

View Dominic Pettifer's Twitter page.