Released RequestReduce 1.8: Making website optimization accessible to even more platforms / by Matt Wrock

This week RequestReduce 1.8 was released expanding its range of platform compatibility along with some minor bug fixes.

Key Features Released

  • Syncing generated sprites and bundles across multiple web servers using sql server is now .net 3.5 compatible. Thanks to Mads Storm (@madsstorm) for migrating the EntityFramework 4 implementation over to PetaPoco
  • Added support for Azure CDN end points. See below for API details needed to enable this.
  • Fixed dashboard and cache flushing to function on IIS6
  • Ability to manually attach the RequestReduce Response Filter earlier in the request processing pipeline via a new API call.
  • Fixed .Less implementation to pass querystring parameters. Thanks

    Andrew Cohen (@omegaluz) for this bug fix.

There were a couple bugs caught by some users the day of release but those were fixed in the first 24 hours and all is stable now. You can now get this version from Nuget or RequestReduce.com. Its been very satisfying hearing from users who use RequestReduce on platforms such as classic ASP and even PHP on IIS and I’m glad to be able to expand this usage even further.

Why RequestReduce is no longer using Entity Framework

The short answer here is compatibility with .Net 3.5. It may seem odd as we stand on the precipice of the release of .Net 4.5 that this would be a significant concern, but I have received several requests to support Sql Server synchronization on .net 3.5. A lot of shops are still on 3.5 and the Sql Server option is a compelling enterprise feature. Its what we use at Microsoft’s EPX organization to sync the generated bundles and sprites across approximately 50 web servers. Since Entity Framework Code First is only compatible with .Net 4.0, we had to drop this in favor of a solution that would work with .Net 3.5.

The reason I chose to originally implement this feature using Entity Framework was mainly to become more familiar with how it worked and compared to the ORM that I have historically used, nHibernate. The data access needs of RequestReduce.SqlServer are actually quite trivial so I felt like it would be a good project to test out this ORM with little risk. In the end, I achieved what I wanted which was to understand how it worked at a nuts and bolts level beyond the white papers and podcasts I had been exposed to. I have to say that it had come a long way since my initial exposure to it a few years back. The code first functionality felt very much like my nHibernate/Fluent nHibernate work flow. It still has some maturing to do. especially in regards to caching.

Mads Storm was kind enough to submit a pull request overhauling the EF implementation using a Micro ORM called PetaPoco. While I certainly could have ported RequestReduce to straight ADO given its simple data needs, the PetaPoco migration was simple given that it follows a similar pattern to Entity Framework. I would definitely recommend PetaPoco to anyone interested in a Micro ORM that needs .Net 3.5 compatibility. I had previously held interested in using a framework like MassiveSimple.Data or Dapper. However all of these make use of the .Net 4 Dynamic type. PetaPoco is the only micro ORM that I am aware of that is compatible with .Net 3.5.

How to integrate RequestReduce with Azure CDN Endpoints

Azure’s CDN (content delivery network) implementation is a little different from most standard CDNs like Akamai. My experiences working with a couple of the major CDN vendors has been that you point your URLs to the same Url that you would use locally with the exception that the host name is one dedicated to static content and whose DNS points to your CDN provider. The CDN provider serves your content from its own cache which is geographically located close to the requesting browser. If the CDN does not have the content cached, it makes a normal HTTP call to the “origin” server (your local server) using the same url it was given but using the host name of your local site. Azure follows this same model with the exception that it expects your CDN content to reside in a directory (physical or virtual) explicitly named “CDN”.

Standard Implementation:

Browser –> http://cdn.yoursite.com/images/logo.png –> CDN Povider (cold cache) –> http://www.yoursite.com/images/logo.png

Azure Implementation:

Browser –> http://azurecdn.com/images/logo.png –> CDN Povider (cold cache) –> http://www.yoursite.com/cdn/images/logo.png

RequestReduce allows applications to serve its generated content via a CDN or cookie less domain by specifying a ContentHost configuration setting. When this setting is provided, RequestReduce serves all of its generated javascript and css and any local embedded resources in the CSS using the host provided in the ContentHost setting. However, because not only the host but also the path differs when using Azure CDN endpoints, this solution fails because http://longazurecdnhostname.com/images/logo.png fails to get content from http://friendlylocalhostname.com/images/logo.png since the content is actually located at http://friendlylocalhostname.com/cdn/images/logo.png. RequestReduce’s ContentHost setting will now work with Azure as long as you include this API call somewhere in your application’s startup code:

RequestReduce.Api.Registry.UrlTransformer = (x, y, z) => z.Replace("/cdn/", "/");

This tells requestReduce that when it generates a URL, remove the CDN directory from the path.

Attaching the RequestReduce response filter early in the request

RequestReduce uses a Response Filter to dynamically analyze your web site’s markup and manipulate it by replacing multiple css and javascript references with bundled javascript and css files transforming the background images in the CSS with sprites where it can. RequestReduce waits until the last possible moment of the request processing pipeline to attach itself to the response so that it has all of the information about the response needed to make an informed decision as to whether or not it should attach itself. This works well in almost all cases.

There are rare cases where an application may have another response filter that either simply does not play nice with other response filters by not chaining its neighboring filter correctly or it manipulates the content of the response in such a way that makes it necessary that RequestReduce filters the content after this filter has performed its manipulations.

I ran into this last week working with the MSDN and Technet Dev Centers in their adoption of RequestReduce. They have a ResponseFilter that gets attached in an MVC controller action filter which is before RequestReduce attaches itself. The nature of chained response filters is that the first filter to attach itself is the last filter to receive the response. Since the dev center Response Filter explicitly removes some excess css and javascript, it is important that RequestReduce receives the content last and is therefore attached first. To accommodate this scenario, I added the following API method that they were able to call in their action filter just before attaching their own method:

RequestReduce.Api.Registry.InstallResponseFilter();

This tells RequestReduce to attach itself Now.

Now excuse me as I slip into my 100% polyester leisure suit…

So what are you waiting for? Head over to Nuget and download RequestReduce today! It will make your site faster or my name isn’t Matt Wrock. Oh…and its Freeeeeeeeeeeeeee!!!!