I agree with Steve. You have the URL rewriter doing 301 redirects, but for every image the page needs, the browser still makes a request to the server first to discover that it's 301 redirected to a CDN Url. The only thing you're saving at this point is the downloading of the content.
Instead of doing that, you can just put a response filter in place that will modify the URLs of the assets before the Response is sent to the client browser. That way, the client browser never has to make any calls to your server for static assets:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.Filter = new CdnResponseFilter(filterContext.RequestContext.HttpContext.Response.Filter);
}
And then the CdnResponseFilter:
public class CdnResponseFilter : MemoryStream
{
private Stream Stream { get; set; }
public CdnResponseFilter(Stream stream)
{
Stream = stream;
}
public override void Write(byte[] buffer, int offset, int count)
{
var data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = Encoding.Default.GetString(buffer);
html = Regex.Replace(html, "src=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
html = Regex.Replace(html, "href=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
byte[] outData = Encoding.Default.GetBytes(html);
Stream.Write(outData, 0, outData.GetLength(0));
}
private static string FixUrl(Match match)
{
//However the Url should be replaced
}
}
The result of this is that all content assets that look like <img src="\Content\whatever.jpg" />
will be converted to <img src="cdn-url.com\Content\whatever.jpg" />