Bundling with Asp.Net MVC
If you are working on Asp.Net
either Web Forms or MVC, you would have come across Bundling & Minification
of JavaScript & Css files.
Background:-
There are hardly any applications which don’t use JavaScript or
Css files and as our application grows, we tend to split these files
logically into multiple files. We then include each file individually on the
HTML page which is sent to the browser. The browser then resolves the
dependencies on these files by making the request to the server for each file
which can slow down the loading of your page.
In .Net 4.5, a powerful tool
was launched which allows you to bundle multiple files into one file, which
then downloaded by the browser in one single request to the server. Below how
it works:-
A typical example of defining a
bundle in BundleConfig.cs is given below:-
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*",
"~/Scripts/requiredif-validation.js"));
The code above just creates a new instance
of ScriptBundle and assigns it the virtual path as "~/bundles/jqueryval". It then invokes the include method to specify which files should
be included in the bundle.
Now that the bundle is registered, we can
reference it in the views using below statement:-
@Scripts.Render("~/bundles/jqueryval")
Now, before you run this, you should know that,
by default, in debug mode bundling is switched off to enable developers debug
the files if they want to. Although you can override this behavior either from
web.config by changing the value of debug to false as shown below:-
<compilation debug="false" targetFramework="4.5" />
Or override these settings by writing below
line in BundleConfig.cs:-
BundleTable.EnableOptimizations
= true;
Once you do
that, next time you run the application, you should see something like below as
the file included on your page on browser:-
<script src="https://yoursitename.com/bundles/jqueryval?v=JzhfglzUfmVF2qo-weTo-kvXJ9AJvIRBLmu11PgpbVY1"></script>
Using CDN with bundling:-
In above
example, we created a bundle which loads all files from our server but what if
you wish to load files from CDN. Files like JQuery are so commonly used that
they are available on almost all CDNs & loading these files from CDN can noticeably
improve the load time of your web page.
Let’s see how
it can be implemented.
First, the
declaration of bundle for a CDN changes as shown below:-
var jqueryBundle = new ScriptBundle("~/bundles/jquery", @"https://ajax.ggleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js").Include(
"~/Scripts/jquery-{version}.js");
bundles.Add(jqueryBundle);
Above we did
two things; first we defined the CDN location of the file and then the local
version of the same file. In debug mode, the local version will be used and in
Release mode, the CDN version will be picked.
The second
step is to enable the CDN usage in RegisterBundles method by adding below
line:-
bundles.UseCdn = true;
Once this is
done, the CDN version will be used in Release mode and the local version will
be used in debug mode which obviously as I stated earlier, you can override it.
Now this is
all good but whenever you use some third party things in your application, you
always have to plan for the failures i.e. in this case let’s say either CDN is
down or the file is no longer hosted there. You can't let this break your
web page and hence you need a fallback option. Luckily, this is available
with bundling in Asp.Net MVC.
Bundling with fallback:-
You can do few
extra things in above CDN bundling code to enable fallback which then pick
these files from your server in case of CDN failure.
First, add the
CdnFallbackExpression in the bundle as mentioned below:-
var jqueryBundle = new ScriptBundle("~/bundles/jquery", @"https://ajax.ggleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js").Include(
"~/Scripts/jquery-{version}.js");
jqueryBundle.CdnFallbackExpression = "window.jquery";
bundles.Add(jqueryBundle);
Here you just
define a JavaScript method which will be called if it fails to load the file
from CDN. You then need to implement this JavaScript method and load the file
from your own server as shown below:-
<script>(window.jQuery)||document.write('<script
src="/bundles/jquery"><\/script>');</script>
The basic idea
for CDN fallback is to check for a type or variable that should be present
after a script load, and if it's not there, try getting that script locally.
Once you do
this, you are ready to use the bundling with CDN with successful fallback
applied and you can be 100% sure that you web page will get the files it needs
from one source or another.