Easy Compression with ASP.NET MVC
ASP.NET MVC already comes with great performance out of the box…due mostly to the lightweight nature of the framework. However, in the never-ending pursuit of faster load times I starting looking into what it would take to put together an Action Filter to compress the output of a controller action. Turns out, it’s pretty damn easy. Here’s what I came up with:
public class CompressAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"]; if (string.IsNullOrEmpty(encodingsAccepted)) return; encodingsAccepted = encodingsAccepted.ToLowerInvariant(); var response = filterContext.HttpContext.Response; if (encodingsAccepted.Contains("deflate")) { response.AppendHeader("Content-encoding", "deflate"); response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); } else if (encodingsAccepted.Contains("gzip")) { response.AppendHeader("Content-encoding", "gzip"); response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); } } }
And you can use it like this:
[Compress] public class ThingController : Controller { ... }
or on a controller action:
public class ThingController: Controller { [Compress] public ActionResult Index() { ... } }
As you can see it really just sets a new filter for the response; GZipStream or DeflateStream depending on what the browser can handle and then sets the appropriate flag. After doing some lightweight testing it looks like the compressed output is on average 18% of the original size. My next task is to do some testing around how long the client takes to actually decompress the response. My guess is that it’s pretty negligible though.