ASP.NET MVC Bundling Cache. (Detecting CSS Files Changes) (Internal Behaviour)

rebuild url with mvc bundle

The problem was that on the server we had in the registry

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Rewrite /v LogRewrittenUrlEnabled set to false

And if you have that then the cache-buster hash is not refreshing when the content i bundle is changed.

bundling in mvc to load new set of files for every release

Bundling in ASP.NET MVC already has a built-in mechanism for handling these type of cache-busting scenarios for release builds as per the "Bundle Caching" section of this documentation :

As long as the bundle doesn't change, the ASP.NET application will request the AllMyScripts bundle using this token. If any file in the
bundle changes, the ASP.NET optimization framework will generate a new
token, guaranteeing that browser requests for the bundle will get the
latest bundle.

This features uses a token within the querystring called v to indicate current "version" of the bundle that looks like :

v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

This functions as a unique identifier for the particular build and as long as nothing in the bundle was changed, it will continue to use it, otherwise a new one would be generated to "bust" any existing caching.

For Non-Release Builds

If you needed to handle this in non-release builds, then I believe you could set the EnableOptimizations property to true to always handle this :

BundleTable.EnableOptimizations = true;

What are the cost/benefits of bundling a single file in ASP.NET?

First, bundling is a once-and-done thing, so I wouldn't focus much on the performance cost of bundling. In other words, the first time the bundle is requested, it must be created, but each subsequent request just statically serves up the previously created file (assuming you don't change the bundle).

Is there value in bundling a single file? Well, that depends on that single file. How large is it? Is it already minimized? If it's a large, unminimized file then yes, there's very much value in bundling it as the bundle version will be a smaller filesize. It's more obvious of course with multiple files, as there you're not only reducing file size but also requests. However, I would still recommend that you always just use bundles. Like I said above, the cost of bundling is occurred only on the first request, which if you're truly concerned about it, could always be requested by you after you publish the site. Then, each further request is statically served until you change the bundle.

Bundling all js files in a single bundle and same with css files

The main disadvantage with this approach is that the browser must download the entirety of your javascript file before it can begin to execute any of it. Most likely that will slow things down, but there are some frameworks/tools that do just that for optimization. It may help with a bunch of small files to overcome the http overhead.

Also, if you change any of the files in the bundle you have to invalidate the cache and give the client an entirely new(large) bundle to download and cache again.

However, as this link explains, such approaches may not be beneficial when http 2.0 is mainstream. And there appears to be a bandwidth threshold where diminishing returns as far as speed vs latency come into play.

Why is my CSS bundling not working with a bin deployed MVC4 app?

The CSS and Script bundling should work regardless if .NET is running 4.0 or 4.5. I am running .NET 4.0 and it works fine for me. However in order to get the minification and bundling behavior to work your web.config must be set to not be running in debug mode.

<compilation debug="false" targetFramework="4.0">

Take this bundle for jQuery UI example in the _Layout.cshtml file.

@Styles.Render("~/Content/themes/base/css")

If I run with debug="true" I get the following HTML.

<link href="/Content/themes/base/jquery.ui.core.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.resizable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.selectable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.accordion.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.autocomplete.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.button.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.dialog.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.slider.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.tabs.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.datepicker.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.progressbar.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.theme.css" rel="stylesheet"/>

But if I run with debug="false". I'll get this instead.

<link href="/Content/themes/base/css?v=myqT7npwmF2ABsuSaHqt8SCvK8UFWpRv7T4M8r3kiK01" rel="stylesheet"/>

This is a feature so you can easily debug problems with your Script and CSS files. I'm using the MVC4 RTM.

If you think it might be an MVC dependency problem, I'd recommend going into Nuget and removing all of your MVC related packages, and then search for the Microsoft.AspNet.Mvc package and install it. I'm using the most recent version and it's coming up as v.4.0.20710.0. That should grab all the dependencies you need.

Also if you used to be using MVC3 and are now trying to use MVC4 you'll want to go into your web.config(s) and update their references to point to the 4.0 version of MVC. If you're not sure, you can always create a fresh MVC4 app and copy the web.config from there. Don't forget the web.config in your Views/Areas folders if you do.

UPDATE: I've found that what you need to have is the Nuget package Microsoft.AspNet.Web.Optimization installed in your project. It's included by default in an MVC4 RTM app regardless if you specify the target framework as 4.5 or 4.0. This is the namespace that the bundling classes are included in, and doesn't appear to be dependent on the framework. I've deployed to a server that does not have 4.5 installed and it still works as expected for me. Just make sure the DLL gets deployed with the rest of your app.



Related Topics



Leave a reply



Submit