HTTP Compression – Why it’s awesome and how to use it in IIS

HTTP Compression is one of the best bang for the buck optimizations available in Microsoft’s IIS webserver. HTTP compression works by compressing data before it’s sent to the client. Images and executables are already heavily compressed, but much of a website’s content is completely uncompressed. IIS can be setup to compress HTML, ASP, ASPX, JS, JSON, CSS, any other uncompressed content found on your web site.

Why Use HTTP Compression?
HTTP Compression first became popular in the days of incredibly slow dialup connections where shaving a few kilobytes off a website was essential. With modern high speed Internet connections it might seem like the compression / decompression time incurred when using HTTP compression would no longer make it beneficial, but there’s still a huge benefit to compression. Where compression really shines in modern web servers, are long distance connections, particularly those over high latency underwater fiber. Any site serving international customers will see a huge performance increase from compressing content prior to transmission. The latency from long haul connections greatly restricts the transmission speeds due to the time it takes acknowledgement flags from the client to reach the server. These TCP ACK flags act as a restrictor for international web transmissions and will leave your server trickling out data in small bursts. The more content that can be compressed the better as compressed data requires fewer packets and thus fewer ACK flags.

Improvements in IIS 7 HTTP Compression
HTTP Compression has long been an afterthought in IIS. IIS 5 required third party add-ons to enable compression and IIS 6 buried the necessary switches deep in the Metabase.xml file. In IIS 7 Microsoft finally provided a simple GUI method to enable both compression of static content (HTML, CSS, JS, etc) and of dynamic content (JSON, ASP, ASPX, etc). Additionally Microsoft changed much of the underlying functionality of their compression module including the method for determining what content to compress. In IIS 6 the metabase.xml file listed all file extensions that would be considered static and dynamic content. Only content on that list would be compressed, which required the list to be updated any time new file extensions were introduced. In IIS 7, compression is based on MIME types with text/*, message/*, and application/javascript being enabled by default. These 3 entries are a catch all for the majority of static and dynamic content, so out of the box most content will already be compressed. Another particularly welcome change is built in CPU based throttling that automatically ceases compression when CPU usage reaches critical levels. This feature alone makes enabling HTTP compression a no brainer for any admin, as there is no longer the worry that high cpu usage during the compression process will slow dynamic generated content delivery. Despite the improvements to the setup of http compression in IIS 7 an effective configuration still requires either manually editing your applicationHost.config file or using the new appcmd.exe configuration utility.

Compression Setup in IIS 6
First you need to enable both dynamic, static, and on demand compression. Dynamic and static are fairly self-explanatory, but On Demand compression requires a bit of explanation. When On Demand compression is enabled IIS will serve content it has never compressed in an uncompressed format to the client, and then compress the content in a background thread for future use. Enabling this feature improves response time for new content by not waiting to first compress the content before trasmitting.

cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/Parameters/HcDoStaticCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/Parameters/HcDoOnDemandCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/Parameters/HcDoDynamicCompression TRUE

Once you’ve enabled http compression you need to enable the two forms of compression supported by IIS, gzip and deflate. For each method you must specify which file extensions should be compressed as dynamic (ScriptFileExtensions) and which extensions should be compressed as static (FileExtensions). You also need to specify compression levels which range from 0-10, with 10 being the highest level of compression. Since we’ve enabled the on demand compression feature we can be a bit more aggressive with the compression levels, setting static to nine, and dynamic to a safer level of six.

cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcDoStaticCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcDoOnDemandCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcDoDynamicCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcFileExtensions “txt” “js” “css” “htm” “html” cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcScriptFileExtensions “exe” “dll” “asp” “aspx” “svc” “xml” cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcOnDemandCompLevel 9 cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/deflate/HcDynamicCompressionLevel 6

cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcDoStaticCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcDoOnDemandCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcDoDynamicCompression TRUE cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcFileExtensions “txt” “js” “css” “htm” “html” cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcScriptFileExtensions “exe” “dll” “asp” “aspx” “svc” “xml” cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcOnDemandCompLevel 9 cscript.exe C:\inetpub\AdminScripts\ADSUtil.vbs Set W3SVC/Filters/Compression/gzip/HcDynamicCompressionLevel 6

Once you’ve enabled compression and setup formats, extensions, and levels it might seem like everything would be complete. Many articles on compression in IIS 6 actually end at this step, but unfortunetly due to a bit of poor planning on Microsoft’s part there is one additional step. In order for compression to function you must create a Web Extension for compression and point it to the correct DLL. Without this nothing will work.

cscript.exe C:\Windows\system32\iisext.vbs /AddFile C:\Windows\System32\inetsrv\gzip.dll 1 “HTTP Compression” 1 “HTTP Compression”

At thit point you can run an iisreset and observe your newly compressed content.

Compression Setup in IIS 7
Enabling compression is IIS 7 became both easier and at the same time more complex. A basic setup requires far fewer commands, and a very basic setup can be completed in the GUI alone. At the same time though Microsoft introduced many additional commands for changing how IIS handles the compression of content. The first step is to install the dynamic compression module, by running the command below. Be warned it takes a while to run so be patient.

start /w pkgmgr.exe /iu:IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic

Similar to IIS 6, you must enable the compression modules in IIS 7. This can be done in the GUI at the server or site level or you can run the two commands below to configure compression at the server level %inetsrv_location%\appcmd.exe set config /section:urlCompression /doStaticCompression:True %inetsrv_location%\appcmd.exe set config /section:urlCompression /doDynamicCompression:True

IIS 7 by default only enables GZIP compression, which is fine as almost all clients support both Gzip and Deflate and specify their preference for GZIP over Deflate in the HTTP header of their request. If you’d like to include support for deflate you can by running the following command %inetsrv_location%\appcmd.exe set config /section:httpCompression /+”[name=’deflate’,doStaticCompression=’True’,doDynamicCompression=’True’,dll=’%Windir%\system32\inetsrv\gzip.dll’]” /commit:apphost

As in IIS 6, IIS 7 includes compression levels from 0 to 10. IIS 7 includes additional functionality that automatically disables compression when the CPU hits high utilization. This feature allows you to set compression at more aggressive levels without compromising the response time of dynamically generated content. Despite this new functionality, a compression level of nine for static content and six for dynamic provide a balance of high compression and low CPU usage. %inetsrv_location%\appcmd.exe set config /section:httpCompression -[name=’gzip’].dynamicCompressionLevel:6 %inetsrv_location%\appcmd.exe set config /section:httpCompression -[name=’gzip’].staticCompressionLevel:9 %inetsrv_location%\appcmd.exe set config /section:httpCompression -[name=’deflate’].dynamicCompressionLevel:6 %inetsrv_location%\appcmd.exe set config /section:httpCompression -[name=’deflate’].staticCompressionLevel:9

With compression enabled and compression levels set you now need to specify additional mime types that are used by your application. By default IIS includes support for javascript and any mimetype starting with text/. You can add additional mime types by first removing the deny all rule at the end of the mimetype list and then adding your required mime types and a new deny all rule.

appcmd.exe set config -section:system.webServer/httpCompression /-“dynamicTypes.[mimeType=’*/*’,enabled=’False’]” /commit:apphost appcmd.exe set config -section:system.webServer/httpCompression /+”dynamicTypes.[mimeType=’application/json’,enabled=’True’]” /commit:apphost appcmd.exe set config -section:system.webServer/httpCompression /+”dynamicTypes.[mimeType=’*/*’,enabled=’False’]” /commit:apphost

At thit point you can run an iisreset and observe your newly compressed content.

Leave a Reply

Your email address will not be published. Required fields are marked *