Thursday, January 22, 2015

Bundling & Minification

Be Careful When Bundling Stylesheets in MVC

 
 Bundling allows you to combine many resources such as stylesheets and scripts so that fewer requests are made to the server. An example on using this feature is below:

public class BundleConfig {
    public static void RegisterBundles(BundleCollection bundles) {
        // combine all of the jquery ui scripts into one bundle
        bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                "~/Scripts/jquery-ui-{version}.js"));

        // combine all of the jquery ui scripts into one bundle
        bundles.Add(new StyleBundle("~/content/themes/base/jquery").Include(
                "~/Content/themes/base/jquery.ui.core.css",
                "~/Content/themes/base/jquery.ui.resizable.css",
                "~/Content/themes/base/jquery.ui.selectable.css",
                "~/Content/themes/base/jquery.ui.accordion.css",
                "~/Content/themes/base/jquery.ui.autocomplete.css",
                "~/Content/themes/base/jquery.ui.button.css",
                "~/Content/themes/base/jquery.ui.dialog.css",
                "~/Content/themes/base/jquery.ui.slider.css",
                "~/Content/themes/base/jquery.ui.tabs.css",
                "~/Content/themes/base/jquery.ui.datepicker.css",
                "~/Content/themes/base/jquery.ui.progressbar.css",
                “~/Content/themes/base/jquery.ui.theme.css"));
    }
}

The above code creates bundles for the jQuery UI scripts and stylesheets. In order to use them in your view you do the following:
@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/content/themes/base/jquery")

One thing you might be tempted to do when bundling your stylesheets is use a shorter name for your bundle such as "~/css/jqueryui", but there is one thing you need to be aware of when you do this.

It is common for stylesheets to include references to images relative to the stylesheet directory.
For example, the default jQuery UI theme is installed in the ~/Content/themes/base/ directory.
Inside of that directory is an images/ folder that contains many of the sprites that jQuery UI uses.

If you create a CSS bundle called "~/css/jqueryui" then you might notice that none of the jQuery UI icons work any more.
This is because the content is expected to be relative to the directory that the stylesheet is in.

When creating the bundle as ~/css/jqueryui, the images are expected to be in ~/css/images.

Unless you are running with debug=”false”, you might not even notice the problem.
This is because by default, when running with debug=”true”, the ASP.net runtime will still make separate requests for every resource in your bundle. When changing to debug=”false”, ASP.net will actually combine all of the files in your bundle and make a single request (per bundle). The request might look similar to:
<link href="/css/jqueryui?v=ps9Ga9601PrzNA2SK3sQXlYmNW3igUv5FOdOPWptyus1" rel="stylesheet"/>

Since the request is being made to /css/jqueryui, the server expects that any relative paths are going to be relative to the /css directory.

To fix this, you need to make sure your CSS bundle names are similar to the physical directory structure of your application. When installing the jQuery UI nuget package, it will put your stylesheets in the directory /content/themes/base/ so you should name your bundle "~/content/themes/base/jqueryui" to make sure that everything works.
For eg.
//If  Images are at:  \Areas\Admin\content\images\   and uses paths like url(images/mainbg.gif); 
//  CSS File is at:  \Areas\Admin\content\main.css
 then:

  bundles.Add(new StyleBundle("~/Areas/Admin/content/css")
                                    .Include("~/Areas/Admin/content/main.css"));
 
 @Styles.Render("~/Areas/Admin/content/css")
 

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More