Visual Studios built-in web server, gzip compression and caching

In case you’ve wondered,

Visual Studios built-in web server (a.k.a. Cassini) does not seem to support gzip compression of requests or cache-control options. IIS Express is your fallback (and a pretty good one too).

I spent an hour or so trying to figure out performance bottlenecks in a ASP.NET MVC 4 application using Googles DevTools. I almost immediately saw that not a single request (of about 17 required to server a page) had a Cache-Control header set. Also, none of the responses had an Encoding header set to gzip. However, I was running this locally and I smelled a rat.

But still, I thought, well here’s some low hanging fruit. But no. I forced compression in my application by setting the web.config element
<urlCompression doStaticCompression="true" />
I also added
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />

in an attempt to enable caching, but no again. No cache-control headers were set.

These are described here for cache control and here for compression.

So, in order to rule out mistakes I reconfigured my application to use IIS Express (v 8) without changing my web.config. And guess what. Content caching was working immediately. But what about Gzip compression? Well, it turns out that the default IIS Express configuration is set to compress files with MIME-type application/x-javascript. In case you aren’t familiar with the x, that stands for experimental. See this explanation. However, all my JS files were served as application/javascript so they weren’t compressed.

To fix that as a default server setting (rather than in your web.config), you can go to the IIS installation folder cd %programfiles%\IIS Express and run the command
appcmd set config /section:httpCompression /staticTypes.[mimeType='application/javascript'].enabled:"true" /commit:apphost

Voilá, compression enabled.

Lesson learned: don’t expect things to be configured correctly by default. Also, don’t use the built-in server, use IIS Express instead. It’s gonna save you some time since it is more likely you will find odd behavior before deploying on a real IIS web server.