15 May 2008 - 2:23 PM / by Dominic Pettifer. 11 Comments for GZip compress your website's HTML/CSS/Script in code.
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.
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.
aspx files are compressed but css, js files are not compressed pls send immediate solution. if you want to give any code to add to the existing code pls specify where it can be added. thanks in advance.
Posted on 10 March 2010 - 5:23 PM / by ishk
The Script and Css compress doesnt work in IIS but if run my website using visual studio 2005 it works.
does i have to change something in IIS ?
Posted on 29 January 2010 - 5:08 PM / by jmpena
To compress the css and javascript use following
this.PreRequestHandlerExecute += new EventHandler(Global_PostReleaseRequestState);
Posted on 1 January 2010 - 8:13 AM / by Amit
Why not to use .htaccess file simply to turn on deflate module?
And also you can make it as Gzip to compress it via PHP
Posted on 20 November 2009 - 11:26 PM / by Pico RG
I don't know why but I got it to work on the localhost but not my server. Very strange.
Posted on 25 September 2009 - 11:31 AM / by Jesse
Just an idea, but wouldnt it be better to implement this into a IHttpHandler?
You would still get the per-request-processing but it will allow you greater control over files/folders?
Stueh.
Posted on 19 July 2009 - 11:30 PM / by Stu
Hi Dominic,
I have just gone through the article its working fine at my end for HTML.
Could you please suggest me how to cache the gzipped version of HTML so that the content is not zippped for each request ?
Your reply would be helpfull for me.
Thanks in Advance,
Karthik.
Posted on 8 June 2009 - 6:37 AM / by Karthik Reddy Chintaparthi
Hello,
I have my application on .net 2.0 i also not able to compress the css and javascript files.
Posted on 27 May 2009 - 9:54 AM / by Dharmender
Do we need to make changes in Metabase.xml file for this to work?
Posted on 27 October 2009 - 6:17 AM / by Anonymous
Thanks for the code! I've had a go at implementing it but it only seems to GZip the .aspx pages and even with the extra line in the IF statement it ignores CSS or Javascript files.
Only thing I can think of is that I'm running .NET 3.5 and it was made for 2.0?
Many thanks,
Ian.
Posted on 7 April 2009 - 3:29 PM / by Ian Black
Do we need to make changes in the Metabase.xml file for the above code to work? Please reply. Or Should we Change anything else?
Posted on 27 October 2009 - 6:22 AM / by Anonymous
Blogged: IHttpModule Gotchas – The Init() Method Can Get Called Multiple Times http://bit.ly/96xioE #aspnet
about 6 hours ago from Echofon@shanselman Give me a free copy of Visual Studio 2010 then! :-)
about 13 hours ago from EchofonRT: @aaronbassett: Guy comes out of the closet - http://bit.ly/aHMg1o - HAHA!! That's hilarious!!
about 17 hours ago from EchofonThis multiple IHttpModule thing has shaken the foundations of my understanding of ASP.NET. I feel a blog post coming.
about 18 hours ago from EchofonI've written the following code to get a pseudo App_StartUp event in my IHttpModule (without relying on Global.asax) http://bit.ly/a2AiNI
about 19 hours ago from Echofon