Monday 27 October 2014

Bundling and Minification

What is Bundle?

A bundle is a logical group of files that is loaded with a single HTTP request. You can create style and script bundle for css and javascripts respectively by calling BundleCollection class Add() method with in BundleConfig.cs file.

Creating Style Bundle

  1. bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.min.css",
  2. "~/Content/mystyle.min.css"));

Creating Script Bundle

  1. bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
  2. "~/Scripts/jquery-1.7.1.min.js",
  3. "~/Scripts/jquery.validate.min.js",
  4. "~/Scripts/jquery.validate.unobtrusive.min.js"));
Above both the bundles are defined with in BundleConfig class as shown below:
  1. public class BundleConfig
  2. {
  3. public static void RegisterBundles(BundleCollection bundles)
  4. {
  5. bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.min.css",
  6. "~/Content/mystyle.min.css"));
  7. bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
  8. "~/Scripts/jquery-1.7.1.min.js",
  9. "~/Scripts/jquery.validate.min.js",
  10. "~/Scripts/jquery.validate.unobtrusive.min.js"));
  11. }
  12. }

Creating Bundle using the "*" Wildcard Character

"*" wildcard character is used to combines the files that are in the same directory and have same prefix or suffix with its name. Suppose you want to add all the scripts files that exist with in "~/Script" directory and have "jquery" as prefix then you can create bundle like below:
  1. bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include("~/Scripts/jquery*.js"));
You can also add all the css that exist with in "~/Content" directory and have ".css" extension(as suffix) like below:
  1. bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/*.css"));

Registering Bundle

All bundles are registered with in Application_Start event of Global.asax file of you web application.
  1. protected void Application_Start()
  2. {
  3. BundleConfig.RegisterBundles(BundleTable.Bundles);
  4. // Other Code is removed for clarity
  5. }

Minification

Minification is technique for removing unnecessary characters (like white space, newline, tab) and comments from the JavaScript and CSS files to reduce the size which cause improved load times of a webpage. There are so many tools for minifying the js and css files. JSMin and YUI Compressor are two most popular tools for minifying the js and css files.
You can also add WebEssentials2012.vsix extension to your VS2012 for minifying the js and css files. This is a great extension for VS2012 for playing with js and css.

Minification with VS2012 and WebEssentials 2012 extension

I would like to share how can you make minify version of you css file using WebEssentials extension and VS2012. This minify version will updated automatically if you will make change in original css file.
 

Performance Optimization with Bundling and Minification

I have done a performance test on a MVC4 application with & without bundling and minification. I have noticed the below result.

Without Bundling and Minification

I have the below css and js files on the layout page and run the application in chrome browser and test no of request and loding time using chrome developer tools as shown below.
  1. <link href="~/Content/Site.css" rel="stylesheet"/>
  2. <link href="~/Content/MyStyle.css" rel="stylesheet"/>
  3. <script src="~/Scripts/jquery-1.7.1.js"></script>
  4. <script src="~/Scripts/jquery-ui-1.8.20.js"></script>
  5. <script src="~/Scripts/jquery.validate.js"></script>
  6. <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

In this test, I have seen, There are 7 request, total data size is 3.96KB and loading time is approximate 296ms.

With Bundling and Minification

I have run the above application with Bundling and Minification of css and js files and test no of request and loding time using chrome developer tools as shown below.
  1. @Styles.Render("~/Content/css")
  2. @Scripts.Render("~/bundles/jquery")

In this test, I have seen, There are only 3 request, total data size is 2.67KB and loading time is approximate 80ms. In this way by using bundling and minification you have reduced the total no of request, size and loading time.

Enabling Bundling and Minification in debug mode

Bundling and minification doesn't work in debug mode. So to enable this featues you need to add below line of code with in Application_Start event of Global.asax.
  1. protected void Application_Start()
  2. {
  3. BundleConfig.RegisterBundles(BundleTable.Bundles);
  4. //Enabling Bundling and Minification
  5. BundleTable.EnableOptimizations = true;
  6. // Other Code is removed for clarity
  7. }

Busting Browser's Cache by Bundling

As you know browsers cache resources based on URLs. When a web page requests a resource, the browser first checks its cache to see if there is a resource with the matched URL. If yes, then it simply uses the cached copy instead of fetching a new one from server. Hence whenever you change the content of css and js files will not reflect on the browser. For this you need to force the browser for refreshing/reloading.
But bundles automatically takes care of this problem by adding a hashcode to each bundle as a query parameter to the URL as shown below. Whenever you change the content of css and js files then a new has code will be generated and rendered to the page automatically. In this way, the browser will see a different url and will fetch the new copy of css and js.


Monday 13 October 2014

Glass Sitecore Mapper

Glass Sitecore Mapper is an object mapping framework for mapping Sitecore items directly onto an object model, this allows you to model your entire Sitecore solution in code. The framework handles reading and writing to fields, creating relationships (parent, child, etc) and much  more . The second aim of the project is to make you Sitecore code unit testable by letting you deal with simple .NET classes that you create and an interface to call data from Sitecore which can be mocked. With Glass Sitecore Mapper you can spend your time focused on solving the business problem and not writing repetitive boiler plate code to mapping data to and from Sitecore.


Features overview:

  • Map Sitecore item fields directly to object properties 
  • Handle type conversion including IEnumerable<> and IList<> 
  • Reading and writing to fields 
  • The ability to create properties for children and parents 
  • Create, Save and Delete objects directly back to Sitecore 
  • Create both classes and interfaces 
  • The service that interacts with Sitecore is interfaced to allow unit testing 
  • Map item properties directly to object properties e.g. item path, item URL 



For more information on these features see the Features page.

The Aim

The aim of the framework is to give the ability to completely model a Sitecore solution and remove the need for complex mapping code, no more of this:
?
1
2
3
4
5
6
7
8
9
10
11
Database db= global::Sitecore.Configuration.Factory.GetDatabase("web");
Item homeItem = db.GetItem("/sitecore/content/home");
HomeClass home = new HomeClass()
{
    Content = homeItem["Content"],
    Title = homeItem["Title"],
    DateTime = DateUtil.IsoDateToDateTime(homeItem["Date"])
    //keep adding mappings and type conversions
};
//do some work
Instead we have something simple like this:
?
1
2
3
4
5
ISitecoreService service = new SitecoreService("web");
HomeClass home = service.GetItem<HomeClass>("/sitecore/content/home");
//no mappings, all handled by the framework
//do some work
For complete tutorial please visit - http://glass.lu/docs/tutorial/index.html.

We all know the very powerful shift to MVC relies on its ability to support TDD approach. But unfortunately, Sitecore MVC is not able to provide this support because of static sitecore context type which is needed to access sitecore API within action method.
We have been thinking about it for sometime, where GlassMapper comes to rescue.

  1. Glass Mapper provides two interfaces ISitecoreContext and ISitecoreService. ISitecoreContext is the more or less implemention of Sitecore Context.So, we can use ISitecoreContext and can mock the context to perform unit tests, which isolates the actionmethod from sitecore dependency.
  2. Another advantage of Glass Mapper is , it avoids boiler plate code. Glass is the concept of ORM. where it will map database to entities. Glass maps items in sitecore db to viewmdel in action method. It uses lazy loading to intialise view model values to sitecore item values hence, there wont be any performance issues. To support lazy loading Glass is dependent on Castle core.

Glass Mapper brief explanation:
What is Glass Mapper?
Glass Mapper is a mapping framework which maps items of sitecore to viewmodel. Means, mapping database to entities, which is nothing but Object Relational Mapping(ORM).
LittleBackground: Sitecore uses template to describe how a content author can enter content. Every item which holds content should be inhertited from template. Means template is a layout of fields in item.
Now , we can imagine template as a TABLE in database and item as ONE ROW in the table and each item Field can be imagined as ONE COLUMN. As per ORM each row represents one instance of entity.
So, it is somewhat clear now, that inorder to use GlassMapper we need entity(representaion of template) which holds all columns (all fields in template). Each such instance represents one ROW(means one item).
For example :
I have one template in sitecore.Which has two fields “name, author both are of type SingleLine”.
Template : Templates/GlassExample
Template Fields:
Field name         Field Type
Author                SingleLine
name                    SingleLine
Then, I will design model as
[SitecoreClass]
public class Example
{
[SitecoreField]
public string name{get;set;}
[SitecoreField]
public string author{get;set;}
}
So, means my model is exact object represention of template. I will discuss about attributes later in the post.
Why Glass Mapper?
If we are not using this mapping framework, then in the datadriven sitecore site we need to access datasource data using sitecore API which requires sitecore context type.
For example:
I have one pagebuild item:
Sitecore/content/sites/mysite/Demo
which consists of DisplayName rendering in presentation details with datasource(content item where I can get name value.)
Datsource : Demo item consists of “name” Field which is singleLine text
DisplayName rendering is a controller rendering with  controller field : Demo actionmethod field : ShowName
Inorder to get the “name” field value in Demo item in code I will access Sitecore API.
public Class DemoController
{
public string ShowName()
{
var item = Sitecore.Context.Presentaion.MVC.RenderingContext.Rendering.CurrentorNull;
(note: may be function call is wrong but my intention is show you how it looks like)
return item.Fields["name"].Value.ToString();
}
}
where we need the item access code everytime which can be treated as boilerplate code we can avoid this using GlassMapper.
and also we can avoid using direct static context type which helps to run unit tests against actionmethod.