Click here to Skip to main content
11,641,081 members (64,266 online)
Click here to Skip to main content

Compress Response and HTML WhiteSpace Remover

, 26 Jul 2009 CPOL 52.6K 354 49
Rate this:
Please Sign up or sign in to vote.
Use of GZipStream or DeflateStream to compress your HTML output in your response when available. Added new class as WhiteSpaceFilter to remove whitespaces from HTML.

Compression

It is obvious that we need to compress our response while passing it to the client. Compressed requests and responses always increase the performance of sites. Nowadays, almost 99 percent of browsers support either Gzip or Deflate compression or both. So, if we can check if the accept-encoding header is present and return a compressed response to the client, then we have just improved our site performance. Just take a look at the code below:

public static void doCompression()
{
     HttpContext context = HttpContext.Current;
     HttpRequest request = context.Request;
     string acceptEncoding = request.Headers["Accept-Encoding"];
     HttpResponse response = context.Response;
     if (!string.IsNullOrEmpty(acceptEncoding))
     {
         acceptEncoding = acceptEncoding.ToUpperInvariant();
         if (acceptEncoding.Contains("GZIP"))
         {
             response.Filter = new GZipStream(context.Response.Filter, 
             CompressionMode.Compress);
             response.AppendHeader("Content-encoding", "gzip");
         }
         else if (acceptEncoding.Contains("DEFLATE"))
         {
             response.Filter = new DeflateStream(context.Response.Filter, 
             CompressionMode.Compress);
             response.AppendHeader("Content-encoding", "deflate");
         }
     }
     response.Cache.VaryByHeaders["Accept-Encoding"] = true;
}

Here, we are checking if the Request header contains [“Accept-Encoding”]. Based on the encoding it supports, we filter the response using GZipStream/ DeflateStream which are available in the System.IO.Compression namespace. Thus the response will be compressed. Only, this will not help the client to render your page properly. You need to add the Content-Encoding header to the response, so it can decompress the response in the client properly. We add a Response header “Accept-Encoding” so that the request is also made using the same encoding it is sending the data in.

You can also remove whitespaces from your HTML to shrink the response. Use this class:

public enum CompressOptions
{
    GZip,
    Deflate,
    None
}

public class WhitespaceFilter : Stream
{
    private GZipStream _contentGZip;
    private DeflateStream _content_Deflate;
    private Stream _content;
    private CompressOptions _options;

    public WhitespaceFilter(Stream content, CompressOptions options)
    {
        if (options == CompressOptions.GZip)
        {
            this._contentGZip = new GZipStream(content, CompressionMode.Compress);
            this._content = this._contentGZip;
        }
        else if (options == CompressOptions.Deflate)
        {
            this._content_Deflate = new DeflateStream(content, 
                  CompressionMode.Compress);
            this._content = this._content_Deflate;
        }
        else
        {
            this._content = content;
        }
        this._options = options;
    }


    public override bool CanRead
    {
        get { return this._content.CanRead; }
    }

    public override bool CanSeek
    {
        get { return this._content.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return this._content.CanWrite; }
    }

    public override void Flush()
    {
        this._content.Flush();
    }

    public override long Length
    {
        get { return this._content.Length; }
    }

    public override long Position
    {
        get
        {
            return this._content.Position;
        }
        set
        {
            this._content.Position = value;
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return this._content.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return this._content.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        this._content.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        byte[] data = new byte[count + 1];
        Buffer.BlockCopy(buffer, offset, data, 0, count);

        string s = System.Text.Encoding.UTF8.GetString(data);
        s = Regex.Replace(s, "^\\s*",string.Empty, RegexOptions.Compiled |
                          RegexOptions.Multiline);
        s = Regex.Replace(s, "\\r\\n", string.Empty, RegexOptions.Compiled | 
                          RegexOptions.Multiline);
        s = Regex.Replace(s, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | 
                          RegexOptions.Multiline); 
        
        byte[] outdata = System.Text.Encoding.UTF8.GetBytes(s);
        this._content.Write(outdata, 0, outdata.GetLength(0));
    }
}

To use it, just write:

internal void Compress()
{
    HttpContext context = HttpContext.Current;
    HttpRequest request = context.Request;
    string acceptEncoding = request.Headers["Accept-Encoding"];
    HttpResponse response = context.Response;
    if (!string.IsNullOrEmpty(acceptEncoding))
    {
        acceptEncoding = acceptEncoding.ToUpperInvariant();
        if (acceptEncoding.Contains("GZIP"))
        {
            //response.Filter = new GZipStream(context.Response.Filter, 
                                //CompressionMode.Compress);
            response.Filter = new WhitespaceFilter(context.Response.Filter, 
                              CompressOptions.GZip);
            response.AppendHeader("Content-encoding", "gzip");
        }
        else if (acceptEncoding.Contains("DEFLATE"))
        {
            //response.Filter = new DeflateStream(context.Response.Filter, 
                                //CompressionMode.Compress);
            response.Filter = new WhitespaceFilter(context.Response.Filter, 
                              CompressOptions.Deflate);
            response.AppendHeader("Content-encoding", "deflate");
        }
    }
    response.Cache.VaryByHeaders["Accept-Encoding"] = true;
}

Note: The Regular Expressions that I have used will remove extra spaces, newlines, and comments from the HTML. Thus, it will reduce the size of the HTML. Also, before using it in production, check how it is working, because you need to change the Regular Expressions according to your needs.

License

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

Share

About the Author

Abhishek Sur
Architect
India India
Did you like his post?

Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.

Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook

Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.

Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.

You can also mail him directly to abhi2434@yahoo.com

Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com

Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 4 Pin
jfriedman15-Mar-12 1:46
memberjfriedman15-Mar-12 1:46 
QuestionJavascript error with CDATA tag Pin
hungud10-Feb-12 18:28
memberhungud10-Feb-12 18:28 
GeneralSomehow Javascript not working Pin
shaikhsamir28-Jul-10 23:22
membershaikhsamir28-Jul-10 23:22 
QuestionIs this Reduce Response Header Size?? Pin
shaikhsamir28-Jul-10 22:49
membershaikhsamir28-Jul-10 22:49 
GeneralQuestion Pin
Guzz23-Feb-10 1:57
memberGuzz23-Feb-10 1:57 
QuestionDoes it really strips down whitespaces? Pin
ranjan_namitaputra2-Oct-09 11:23
memberranjan_namitaputra2-Oct-09 11:23 
AnswerRe: Does it really strips down whitespaces? Pin
Abhishek Sur5-Nov-09 21:06
memberAbhishek Sur5-Nov-09 21:06 
GeneralMy Vote of 5 Pin
albert_cook11-Aug-09 21:16
memberalbert_cook11-Aug-09 21:16 
GeneralRe: My Vote of 5 Pin
Abhishek Sur11-Aug-09 22:15
memberAbhishek Sur11-Aug-09 22:15 
QuestionHow About a Little More efficient Example using your code ;) Pin
Member 460136511-Aug-09 7:44
memberMember 460136511-Aug-09 7:44 
AnswerRe: How About a Little More efficient Example using your code ;) Pin
Abhishek Sur11-Aug-09 22:15
memberAbhishek Sur11-Aug-09 22:15 
GeneralRe: How About a Little More efficient Example using your code ;) Pin
João Rollo de Sá11-Aug-09 23:57
memberJoão Rollo de Sá11-Aug-09 23:57 
GeneralRe: How About a Little More efficient Example using your code ;) Pin
Abhishek Sur12-Aug-09 2:08
memberAbhishek Sur12-Aug-09 2:08 
GeneralExample request Pin
Pawel7535-Aug-09 23:22
memberPawel7535-Aug-09 23:22 
GeneralRe: Example request Pin
Abhishek Sur11-Aug-09 22:16
memberAbhishek Sur11-Aug-09 22:16 
GeneralRe: Example request Pin
Mohammed Aziz Elnahrawi28-May-10 23:37
memberMohammed Aziz Elnahrawi28-May-10 23:37 
GeneralWhat' a about user serving speed Pin
Hristo Bojilov27-Jul-09 22:41
memberHristo Bojilov27-Jul-09 22:41 
GeneralRe: What' a about user serving speed Pin
Abhishek Sur28-Jul-09 22:19
memberAbhishek Sur28-Jul-09 22:19 
GeneralRe: What' a about user serving speed Pin
Andre Luiz V Sanches13-Aug-09 12:29
memberAndre Luiz V Sanches13-Aug-09 12:29 
GeneralPlease send me an example. Pin
lisekR27-Jul-09 4:48
memberlisekR27-Jul-09 4:48 
GeneralRe: Please send me an example. Pin
Abhishek Sur27-Jul-09 12:45
memberAbhishek Sur27-Jul-09 12:45 
GeneralCool Buddy Pin
Abhijit Jana26-Jul-09 13:24
mvpAbhijit Jana26-Jul-09 13:24 
GeneralRe: Cool Buddy Pin
Abhishek Sur26-Jul-09 21:44
memberAbhishek Sur26-Jul-09 21:44 
GeneralNice just a few questions Pin
spoodygoon26-Jul-09 6:36
memberspoodygoon26-Jul-09 6:36 
GeneralRe: Nice just a few questions Pin
Abhishek Sur26-Jul-09 9:14
memberAbhishek Sur26-Jul-09 9:14 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150731.1 | Last Updated 27 Jul 2009
Article Copyright 2009 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid