7

I am adding in gzipping to all my static content, and html outputs from my .net 4 site.

I also have compression enabled in IIS 7.5 (both static and dynamic), and what I am finding is that enabling compression in IIS, overwrites my Vary: Accept-Encoding header for these resources.

So, what I am wondering is, is there really a need to enable compression in IIS, since I already am gzipping things?

So, I've done a some testing, and what I found follows:

Utilizing IIS Static and Dynamic Compression, with code compression:
CPU Load: 35%
Memory Load: 28M

Utilizing IIS Static and Dynamic Compression, without code compression:
CPU Load: 34%
Memory Load: 28M

Non-Utilizing Static and Dynamic Compression In IIS, with code compression:
CPU Load: 14%
Memory Load: 32M

So, based on my findings, I agree, there is no need to utilize IIS compression, when doing this in code. Even though memory consumption is a bit higher, CPU Load is significantly enough lower to make the in-code compression much more efficient for serving the files.

Now, really my whole point of this was to find out and get rid of the IIS overwriting of the Vary: Accept-Encoding header. Which, it seems to have no effect when IIS compression is enabled or not. The header still does not get added... so, can you help with that?

Here is the code for the caching that I am implementing, please note that prior to firing the method containing this code, I am clearing the headers via, context.Response.ClearHeaders():

    With context.Response
        .AddHeader("Cache-Control", "store, cache")
        .AddHeader("Pragma", "cache")
        .AddHeader("Cache-Control", "max-age=21600")
        .AddHeader("ETag", Date.Now.Ticks)
        .AddHeader("Expires", DateTime.Now.AddYears(1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT")
        .AddHeader("Vary", "Accept-Encoding")
        .AppendHeader("Vary", "Accept-Encoding")
        .Cache.SetVaryByCustom("Accept-Encoding")
        .Cache.SetOmitVaryStar(True)
        .Cache.VaryByParams.IgnoreParams = True
        .Cache.SetAllowResponseInBrowserHistory(True)
        .Cache.SetCacheability(Web.HttpCacheability.Public)
        .Cache.SetValidUntilExpires(True)
        .Cache.SetLastModified(DateTime.Now.AddYears(-1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT")
        .CacheControl = "public" '
        .Expires = 24 * 60 * 366
        .ExpiresAbsolute = DateTime.Now.AddYears(1).ToString("ddd, dd MMM yyyy hh:mm:ss") + " GMT"
    End With
Kevin
  • 2,684
  • 6
  • 35
  • 64
  • I am wondering the opposite: Is there really a need to compress in code when IIS offers compression? Figure out if there really is a good reason why you are doing this. – Kevin P. Rice Apr 07 '12 at 05:11
  • Why are you adding encoding of your own? And what kind of encoding it is? – Akash Kava Apr 07 '12 at 05:19
  • I want to make sure that static resources are compressed. Most shared hosting sytems do not enable compression by default. so by doing in code, ensures that on these systems the resources will get gzipped. Only "text" files are compressed... css, js, html, font files, etc... – Kevin Apr 09 '12 at 13:40
  • @o7thWebDesign Without getting neck deep in your problem, I have two suggestions: (1) I have doubts that your testing is accurate for one specific reason: It sounds like you are serving static content dynamically. This would preclude all static compression and caching. Best scalability would result if no static content was served through the ASP.NET pipeline. (2) On the Vary header, I don't have enough detailed understanding of all the cache control headers to speak to what is proper here. Study all the config file settings (http://msdn.microsoft.com/en-us/library/aa347461%28v=vs.90%29.aspx). – Kevin P. Rice Apr 10 '12 at 23:44
  • Actually, it is served dynamically. All scripts, stylesheets, images, and fonts are passed through an httphandler to set the proper caching headers. This is only necessary because not all 3rd party hosts do this through IIS. – Kevin Apr 11 '12 at 14:50
  • Overwriting 'Vary' header is a known bug in IIS Gzip module. Please vote here: http://connect.microsoft.com/VisualStudio/feedback/details/758474/iis-gzip-compression-filter-removes-pre-existing-vary-header – Dmitry Nov 21 '12 at 03:56

1 Answers1

5

You need to specifically know which MIME types you are applying compression to in code. Then you can disable IIS compression for those MIME types.

Your .config file should look approximately like the one below. You will note that the MIME types compression is applied to are all listed. Judiciously turn off compression for MIME types either in your code or in IIS such that the content compressed in code does not get compressed by IIS, and vise-versa.

For instance, if your HTML is all compressed in code, you could specify:

    <add mimeType="text/html" enabled="false" />

Excerpt from applicationHosts.config file:

<system.webServer>
<httpCompression
    directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files"
    dynamicCompressionDisableCpuUsage="90"
    dynamicCompressionEnableCpuUsage="80"
    maxDiskSpaceUsage="100" minFileSizeForComp="2700"
    noCompressionForRange="true"
    sendCacheHeaders="false"
    staticCompressionDisableCpuUsage="100"
    staticCompressionEnableCpuUsage="80"
    >
    <scheme name="gzip"
        dll="%Windir%\system32\inetsrv\gzip.dll"
        dynamicCompressionLevel=”4”
        staticCompressionLevel=”7” />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/json" enabled="true" />
        <add mimeType="application/xml" 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="application/json" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/rss+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="application/xml" enabled="true" />
        <add mimeType="image/svg+xml" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>
<urlCompression doDynamicCompression="true"
    dynamicCompressionBeforeCache=”true” />
</system.webServer>

Please note that if you modify applicationHosts.config it affects ALL of the web sites on your server, so you need to be aware that any web sites that do not apply compression in code will then not be compressed at all.

Also note, binary content generally should not be compressed (i.e., images, video). These resources are already compressed in their respective containers (i.e., .JPG, .MP4). Ensure that you aren't compressing content types that are already compressed.

I've written more detail in regards to compression settings that you may want to check out in my answer here: https://stackoverflow.com/a/10051876/733805.

Community
  • 1
  • 1
Kevin P. Rice
  • 5,550
  • 4
  • 33
  • 39
  • Definately handy, but what I did was make sure that if someone who uses the system, installs it on a server that does not allow this type of higher level access can do the comressions – Kevin Apr 09 '12 at 13:41
  • So on my test server (in my basement), I have IIS 7.5 setup to do the compression for all static and dynamic resources. I also have my code setup to gzip any js, css, html output, font files, etc... Because I need to account for those that may use my system on a server that does not have compression enabled in IIS. What my concern is that on the servers that do enable the compression, will it waste server resources? And is it really necessary? – Kevin Apr 09 '12 at 13:44
  • 1
    @o7thWebDesign I am fairly certain that it will waste resources if compression is enabled in both places. I don't know if IIS detects content is already compressed. IIS might double-encrypt causing corruption or larger file sizes. You'd have to test for that. Second, I am not certain whether IIS compression can be controlled a the local web.config; and, if so, some admins might lock it out anyway. Two schools of thought: (1) Pursue the complexity of your own compression to offer as a feature; or, (2) Leave compression as a reason for users to find better hosting. – Kevin P. Rice Apr 09 '12 at 16:50
  • @o7thWebDesign Compression is only necessary if you're concerned with saving bandwidth and improving page loading speed. – Kevin P. Rice Apr 09 '12 at 16:52
  • :) Definately looking to improve load speeds :) I did some testing. I'll post it as an answer so I can format better =) – Kevin Apr 10 '12 at 13:25
  • @o7thWebDesign Looking forward to your post. There are a slew of compression settings (http://msdn.microsoft.com/en-us/library/aa347461%28v=vs.90%29.aspx) that I admit to have never thoroughly investigated. – Kevin P. Rice Apr 10 '12 at 18:06
  • :) Sorry, didn;t post as an answer, (just didn't want to accept my own as the answer) =) Editted the initial question. FYI, I am building this to build myself a CDN for my site rendering engine – Kevin Apr 10 '12 at 20:45