How to implement GZip compression in ASP.NET?

98,534

Solution 1

For compressing JS & CSS files you actually have to handle that at the IIS level, since these files are rendered directly without the ASP.NET runtime.

You could make a JSX & CSSX extension mapping in IIS to the aspnet_isapi.dll and then take advantage of your zip code, but IIS is likely to do a better job of this for you.

The content-encoding header tells the browser that it needs to unzip the content before rendering. Some browsers are smart enough to figure this out anyway, based on the shape of the content, but it's better to just tell it.

The Accept-encoding cache setting is there so that a cached version of the gzipped content won't be sent to a browser that requested only text/html.

Solution 2

Here is the solution for css and javascript files. Add the following code to <system.webServer> inside your web.config file:

<configuration>
  ...
  <system.webserver>
     ...
      <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
          <add mimeType="text/*" enabled="true"/>
          <add mimeType="message/*" enabled="true"/>
          <add mimeType="application/javascript" enabled="true"/>
          <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
          <add mimeType="text/*" enabled="true"/>
          <add mimeType="message/*" enabled="true"/>
          <add mimeType="application/javascript" enabled="true"/>
          <add mimeType="*/*" enabled="false"/>
        </staticTypes>
      </httpCompression>
      <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
    ...
  </system.webserver>
  ...
<configuration>

Credit: How to GZip on ASP.NET and GoDaddy

Solution 3

this may be useful for you try it out, this accepts deflate and gzip compression.

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (app.Context.CurrentHandler == null)
            return;

        if (!(app.Context.CurrentHandler is System.Web.UI.Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

        if (acceptEncoding == null || acceptEncoding.Length == 0)
            return;

        acceptEncoding = acceptEncoding.ToLower();

        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // deflate
            app.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
        else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
    } 

Solution 4

The reason it's only compressing your ASPX file is that the code you have written is only embedded in the ASPX file. An ASPX file is a separate request from any linked content it contains. So if you have an ASPX page that contains:

<img src="www.example.com\exampleimg.jpg" alt="example" />

This would amount to 2 requests (DNS lookups aside) from your browser to the resources:

  1. for the aspx page and
  2. for the image contained by the aspx page.

Each request has it own response steam. The code you have posted is attaching to the ASPX response stream only, which is why only your ASPX page is being compressed. Lines 1 & 2 of your posted code are essentially taking over the normal response stream of the page and injecting some "middle man" code that in this case eats and compresses the normal output stream with a GZip stream and sends that down the wire instead.

Lines 3 & 4 are setting up the response headers. All http requests and responses have headers that are sent prior to the content. These set up the request/response so that the server and client know what is being sent and how.

In this case Line 3 is informing the client browser that the response stream is compressed via gzip and therefore needs to be de-compressed by the client browser prior to display.

And Line 4 is simply turning on the Accept-Encoding header of the response. This would otherwise have been absent from the response.

There are pluggable modules you can write/obtain that allow you to compress a multitide of other MIME type such as *.js and *.css but you're better off just using the built in compression functionality of IIS.

You haven't said which verson of IIS you are using but if it were IIS 7.0, it would require that you include something like the following into the <system.webserver> section of you web.config file:

<httpCompression> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> 
 <staticTypes>
         <add mimeType="text/*" enabled="true" />
      </staticTypes>
</httpCompression> 
<urlCompression doStaticCompression="true" /> 

..

Richard

Solution 5

In IIS7 all requests go to .net, so you would have to create an HttpModule that added those headers to all responses.

Without IIS7, and on shared hosting, you would have to creare a handler that mapped a .net file extention that you are not using (like .asmx) and in the web.config specify that .asmx files go to your HttpHandler which is set to rewrite the path to .jpg or whatever and set the header there too.

Share:
98,534

Related videos on Youtube

djmzfKnm
Author by

djmzfKnm

WebDev

Updated on July 05, 2022

Comments

  • djmzfKnm
    djmzfKnm almost 2 years

    I am trying to implement GZip compression for my asp.net page (including my CSS and JS files). I tried the following code, but it only compresses my .aspx page (found it from YSlow)

    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;
    

    The above code is only compressing my .aspx page code (markup) not the CSS and JS files which is included as external files. Please tell me how can I implement GZip compression in ASP.NET using code (because I am on shared hosting server where I don't have access to IIS Server configurations). And also in the above code I am not getting the last two lines, why they are used and what's the purpose of these lines. Please explain!

  • djmzfKnm
    djmzfKnm over 15 years
    Hi @Ben, Can you please tell me how to compress my files using IIS, what all settings I have to perform, Although I don't have access to IIS configurations, but I'll try to do it. Please tell me how to compress files using IIS ?? Thanks!
  • irag10
    irag10 over 11 years
    stackoverflow.com/a/6992948/8479 details the simple change to web.config that's needed for IIS7 or greater.
  • Rafael Merlin
    Rafael Merlin over 9 years
    Thanks a lot for this code. I needed to gzip/deflate the content a specific site I have no access to IIS console and this helped me. Just a question though: This code appears to be deflating all the aspx files and gziping CSS and ScriptResources, but it is not gziping any .js files. Is there a way of doing that? Thanks.
  • rakeshyadvanshi
    rakeshyadvanshi about 8 years
    Really awsome descriptions
  • oligofren
    oligofren over 7 years
    This is wrong, as you are not handling quality instruction like this: gzip;q=0,deflate. singular.co.nz/2008/07/…
  • JeffT
    JeffT almost 7 years
    the last line should be removed
  • Carlos R Balebona
    Carlos R Balebona over 5 years
    true, but I'd actually add the opening <system.webServer> ... so we know where to put the configuration.
  • Zeeshan Ahmad Khalil
    Zeeshan Ahmad Khalil about 4 years
    I added the same code but the files are not getting compressed
  • Zeeshan Ahmad Khalil
    Zeeshan Ahmad Khalil about 4 years
    Do I need to add something else?