Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Bundling cache. (Detecting css files changes) (internal behaviour)

I've been diving into ASP.NET MVC internal functionality much (different reasons), but still can not cover all the behaviour. One of those which I did not is subj.

The way it works is the following:

if I bundle some files (css files for instance), the framework detects those changes and generates new id for the new bundle (to make it easy for browsers to refresh the changes) like href="/Content/css?v=qartPE4jGe-l1U0I7kNDZPZzVTdh0kT8VBZZA_uURjI1".

What I am actually trying to understand:

  1. How exactly the framework (that's possibly not MVC but .NET stuff) detects that the files are changed (as there are no directory watchers active (as I can change the file even when web-server if off-line) to see the file changes live, and also the system detects actually the file content changes (I tried just to re-save files without changing their contents and the bundle number did not change as well))? (I consider that obviously the system can not compare every file content to detect its changings on every request came).

  2. Where (and how) the frameworks stores current bundle id and how it stores previous versions (as previous bundles are still available when go to their urls)?

Thanks a lot!

like image 1000
Agat Avatar asked Aug 26 '13 23:08

Agat


People also ask

What is the advantage of bundling in MVC?

Bundling and Minification provide us a way to both reduce the number of requests needed to get JS and CSS resource files and reduce the size of the files themselves, thereby improving the responsiveness of our apps. They are nice little optimizations for our MVC apps that can improve performance and add responsiveness.

How does bundling increase performance in MVC?

To improve the performance of the application, ASP.NET MVC provides inbuilt feature to bundle multiple files into a single, file which in turn improves the page load performance because of fewer HTTP requests.

How bundling and minification works in MVC?

ASP.NET MVC Application performance can be improved with the help of Bundling and Minification. Bundling and Minification are two separate techniques to reduce load time. Bundling reduces the number of requests to the Server, whereas Minification reduces the size of the requested assets.

How does bundling use browser cache capability?

Busting Browser's Cache by Bundling As we upload the changes in the static resources such as CSS and JS files on the live server, the resources changes but it does not update on the Browser, because the Browser's cache resources are based on URLs automatically.


1 Answers

The ASP.NET Optimization framework caches the bundle response in HttpContext.Cache and uses a CacheDependency to monitor each file in the bundle for changes. This is why updating the files directly invalidates the cache and regenerates the bundle.

The bundle file name is a hash of the bundle contents which ensures the URL changes when any of the bundle files are modified. The bundle's virtual path is used as the cache key.

The relevant code from the library (note this is slightly out of date but I believe the logic is still the same):

internal BundleResponse GetBundleResponse(BundleContext context)
{
    // check to see if the bundle response is in the cache
    BundleResponse bundleResponse = Bundle.CacheLookup(context);
    if (bundleResponse == null || context.EnableInstrumentation)
    {
        // if not, generate the bundle response and cache it
        bundleResponse = this.GenerateBundleResponse(context);
        if (context.UseServerCache)
        {
            this.UpdateCache(context, bundleResponse);
        }
    }
    return bundleResponse;
}

private void UpdateCache(BundleContext context, BundleResponse response)
{
    if (context.UseServerCache)
    {
        // create a list of all the file paths in the bundle
            List<string> list = new List<string>();
        list.AddRange(
            from f in response.Files
            select f.FullName);
        list.AddRange(context.CacheDependencyDirectories);
        string cacheKey = Bundle.GetCacheKey(context.BundleVirtualPath);
        // insert the response into the cache with a cache dependency that monitors
        // the bundle files for changes
        context.HttpContext.Cache.Insert(cacheKey, response, new CacheDependency(list.ToArray()));
        context.HttpContext.Response.AddCacheItemDependency(cacheKey);
        this._cacheKeys.Add(cacheKey);
    }
}

Finally as for old bundle URLs working, I think you will find they are either returned from your browser cache or actually return the latest version of the bundle since the bundle path doesn't change, only the version query string.

like image 148
Ben Foster Avatar answered Nov 02 '22 08:11

Ben Foster