Click here to Skip to main content
Click here to Skip to main content

Compress Response and HTML WhiteSpace Remover

By , 26 Jul 2009
 

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)

About the Author

Abhishek Sur
Team Leader
India India
Member
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

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 4memberjfriedman15 Mar '12 - 1:46 
QuestionJavascript error with CDATA tag [modified]memberhungud10 Feb '12 - 18:28 
GeneralSomehow Javascript not workingmembershaikhsamir28 Jul '10 - 23:22 
QuestionIs this Reduce Response Header Size??membershaikhsamir28 Jul '10 - 22:49 
GeneralQuestionmemberGuzz23 Feb '10 - 1:57 
QuestionDoes it really strips down whitespaces?memberranjan_namitaputra2 Oct '09 - 11:23 
AnswerRe: Does it really strips down whitespaces?memberAbhishek Sur5 Nov '09 - 21:06 
GeneralMy Vote of 5memberalbert_cook11 Aug '09 - 21:16 
GeneralRe: My Vote of 5memberAbhishek Sur11 Aug '09 - 22:15 
QuestionHow About a Little More efficient Example using your code ;)memberMember 460136511 Aug '09 - 7:44 
AnswerRe: How About a Little More efficient Example using your code ;)memberAbhishek Sur11 Aug '09 - 22:15 
GeneralRe: How About a Little More efficient Example using your code ;)memberJoão Rollo de Sá11 Aug '09 - 23:57 
GeneralRe: How About a Little More efficient Example using your code ;)memberAbhishek Sur12 Aug '09 - 2:08 
GeneralExample requestmemberPawel7535 Aug '09 - 23:22 
GeneralRe: Example requestmemberAbhishek Sur11 Aug '09 - 22:16 
GeneralRe: Example requestmemberMohammed Aziz Elnahrawi28 May '10 - 23:37 
GeneralWhat' a about user serving speedmemberHristo Bojilov27 Jul '09 - 22:41 
GeneralRe: What' a about user serving speedmemberAbhishek Sur28 Jul '09 - 22:19 
GeneralRe: What' a about user serving speedmemberAndre Luiz V Sanches13 Aug '09 - 12:29 
GeneralPlease send me an example.memberlisekR27 Jul '09 - 4:48 
GeneralRe: Please send me an example.memberAbhishek Sur27 Jul '09 - 12:45 
GeneralCool BuddymvpAbhijit Jana26 Jul '09 - 13:24 
GeneralRe: Cool BuddymemberAbhishek Sur26 Jul '09 - 21:44 
GeneralNice just a few questionsmemberspoodygoon26 Jul '09 - 6:36 
GeneralRe: Nice just a few questionsmemberAbhishek Sur26 Jul '09 - 9:14 

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

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