Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Built-in GZip/Deflate Compression on IIS 7.x


IIS 7 improves internal compression functionality dramatically making it much easier than previous versions to take advantage of compression that’s built-in to the Web server. IIS 7 also supports dynamic compression which allows automatic compression of content created in your own applications (ASP.NET or otherwise!). The scheme is based on content-type sniffing and so it works with any kind of Web application framework.

While static compression on IIS 7 is super easy to set up and turned on by default for most text content (text/*, which includes HTML and CSS, as well as for JavaScript, Atom, XAML, XML), setting up dynamic compression is a bit more involved, mostly because the various default compression settings are set in multiple places down the IIS –> ASP.NET hierarchy.

Let’s take a look at each of the two approaches available:

  • Static Compression
    Compresses static content from the hard disk. IIS can cache this content by compressing the file once and storing the compressed file on disk and serving the compressed alias whenever static content is requested and it hasn’t changed. The overhead for this is minimal and should be aggressively enabled.
  • Dynamic Compression
    Works against application generated output from applications like your ASP.NET apps. Unlike static content, dynamic content must be compressed every time a page that requests it regenerates its content. As such dynamic compression has a much bigger impact than static caching.

How Compression is configured

Compression in IIS 7.x  is configured with two .config file elements in the <system.WebServer> space. The elements can be set anywhere in the IIS/ASP.NET configuration pipeline all the way from ApplicationHost.config down to the local web.config file. The following is from the the default setting in ApplicationHost.config (in the %windir%\System32\inetsrv\config forlder) on IIS 7.5 with a couple of small adjustments (added json output and enabled dynamic compression):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
      <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="9" />
      <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="*/*" enabled="false" />
      </dynamicTypes>
      <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="*/*" enabled="false" />
      </staticTypes>
    </httpCompression>
    
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />
    
  </system.webServer>
</configuration>

You can find documentation on the httpCompression and urlCompression keys here respectively:

http://msdn.microsoft.com/en-us/library/ms690689%28v=vs.90%29.aspx

http://msdn.microsoft.com/en-us/library/aa347437%28v=vs.90%29.aspx

The httpCompression Element – What and How to compress

Basically httpCompression configures what types to compress and how to compress them. It specifies the DLL that handles gzip encoding and the types of documents that are to be compressed. Types are set up based on mime-types which looks at returned Content-Type headers in HTTP responses. For example, I added the application/json to mime type to my dynamic compression types above to allow that content to be compressed as well since I have quite a bit of AJAX content that gets sent to the client.

The UrlCompression Element – Enables and Disables Compression

The urlCompression element is a quick way to turn compression on and off. By default static compression is enabled server wide, and dynamic compression is disabled server wide. This might be a bit confusing because the httpCompression element also has a doDynamicCompression attribute which is set to true by default, but the urlCompression attribute by the same name actually overrides it.

The urlCompression element only has three attributes: doStaticCompression, doDynamicCompression and dynamicCompressionBeforeCache. The doCompression attributes are the final determining factor whether compression is enabled, so it’s a good idea to be explcit! The default for doDynamicCompression='false”, but doStaticCompression="true"!

Posted in IIS7   ASP.NET  

The Voices of Reason


 

Cesar
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

Great article.

We've been using this option, however we've encountered a problem with clients using a version of IE6 that has problems understanding compressed js - versions on Win 2000 for example.

What I know is that the IIS configuration does not allow selective compression according to a custom predicate (in this case the browser's version) which makes this non-usable for dynamic javascript in case you want your site to support IE6 as well.

We had to disable compression for javascript through IIS and keep doing it programmatically

Rick Strahl
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Cesar - that seems odd. Browsers/clients should request whether they support gzip/deflate via the Accept header, which as far as I know IIS does do (it has to). Are you saying that weird version of IE is not sending the right accept header then?

Wayne Ye
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Cesar, gzip on IE6 should be a "known issue", please refer: http://stackoverflow.com/questions/1456112/known-issues-with-gzip-and-ie6

@Rick, I am your blog reader since 6 months ago, very pleased to see this blog talking about gzip compression, casually I wrote a blog entry last year also tried to describe gzip in IIS/ASP.NET (links below), could you kindly take a look at it and raise your precious suggestion:)
http://www.codeproject.com/Articles/186233/Utilize-gzip-compression-in-IIS.aspx
http://wayneye.com/Blog/IIS-Gzip-Compression

Cesar
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Rick - Yes, that's exactly what I am saying. The following code is taken from the ToolkitScriptManager of the AjaxControlToolkit which is aimed at this problem

if (!request.Browser.IsBrowser("IE") || (6 < request.Browser.MajorVersion))
{
foreach (string acceptEncoding in (request.Headers["Accept-Encoding"] ?? "").ToUpperInvariant().Split(','))
{
if ("GZIP" == acceptEncoding)
{
// Browser wants GZIP; wrap the output stream with a GZipStream
response.AddHeader("Content-encoding", "gzip");
outputStream = new GZipStream(outputStream, CompressionMode.Compress);
break;
}
else if ("DEFLATE" == acceptEncoding)
{
// Browser wants Deflate; wrap the output stream with a DeflateStream
response.AddHeader("Content-encoding", "deflate");
outputStream = new DeflateStream(outputStream, CompressionMode.Compress);
break;
}
}
}

The code indicates that some versions of IE6 (older ones) send an incorrect header (or have a bug with compressed javascript - either way :) ) and therefore the AjaxControlToolkit for example does not compress javascript for IE6 at all since it can't know the exact version and can't be sure whether the client can handle it

Cesar
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Wayne - thanks, I'll check it out

vivitron
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

Good article... I tried to use dynamic compression in my latest web app, but I finally implemented it programmatically because it seemed unreliable in regards to when it would compress. Using IIS 7.0 - have not tried IIS 7.5.

The other nice thing about doing it in the app is that you can flip a switch to turn it all off without console access.

Carlos
May 05, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Cesar, one thing I think you could do is use URL Rewrite and use a condition that matches User Agent for IE6 and the requests in question and rewrite the Accept header to blank so that it does not do compression.

Cory
July 07, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

Cannot seem to get it to work for JSON, returned from a JsonResult in MVC 3.0. Everything else is compressing nicely though.

Xuanyi
August 26, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

For those running iis on 64bit version. The applicationHost.config file is located under %WINDIR%\SysWOW64\inetsrv\Config. See http://xuanyili.com/2011/08/26/configure-gzip-http-compression-on-iis-7/

Bill Hebb
September 23, 2011

# re: Built-in GZip/Deflate Compression on IIS 7.x

Rick:
AFAIK IIS 7.5 sets a threshold of the number of hits within a period of time before any compression regardless of the web.config settings, occurs. That threshold (frequentHitThreshold) has to be set to something reasonable before any benefits can be seen, and most shared servers won't allow the default to be overridden. See http://www.iis.net/ConfigReference/system.webServer/serverRuntime

Furthermore, the old technique of deflatestream compressing in the global asax won't work on the IIS 7.5 newer integrated app pool.

Thoughts?

Best,
Bill

Cesar
May 14, 2012

# re: Built-in GZip/Deflate Compression on IIS 7.x


Thomas
December 09, 2012

# re: Built-in GZip/Deflate Compression on IIS 7.x

"The elements can be set anywhere in the IIS/ASP.NET configuration pipeline all the way from ApplicationHost.config down to the local web.config file."

This seems to not be the case with IIS8. Applicationhost.config includes this:

<section name="httpCompression" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />

Which means that web.config cannot override the compression settings (eg. turn on dynamic gzip).

Usha chowdary
June 08, 2017

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Rick

Great article...

I added httpCompression and urlCompression in webconfig file But i cannot able to see any difference. in Localhost can we see that difference ? or only in https servers ?


Rick Strahl
June 08, 2017

# re: Built-in GZip/Deflate Compression on IIS 7.x

@Usha - Compression doesn't kick in right away. IIS decides to cache and gzip content only after content gets accessed a few times.

 

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2017