Friday, August 19, 2016

Bundling CSS and JavaScript with Sitecore

In terms of optimizing web pages for a better user experience and less load on the web server, bundling of css and javascript files can provide one of the quickest wins. The benefits of bundling the css and javascript are:
  1. Less HTTP requests on the web server - for example a single javascript file request instead of 10+, which is a real help when a server is under load.
  2. Less file size as the bundle is minified.
  3. "Bundling and minification in ASP.NET 4.5 is performed at runtime, so that the process can identify the user agent (for example IE, Mozilla, etc.), and thus, improve the compression by targeting the user browser (for instance, removing stuff that is Mozilla specific when the request comes from IE)."

Setting up bundling in your Sitecore solution (web forms)

  1. Install the Microsoft.AspNet.Web.Optimization nuget package. In this example I installed version 1.1.3
  2. Because the the nuget package above has some dependencies that Sitecore uses, set the WebGrease and Newtonsoft.json references to Copy Local false. As we don't want to overwrite the newer versions installed by Sitecore.
  3. The following dependent assembly changes need to be inside the web.config file
  4. <dependentAssembly>
      <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
      <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
    </dependentAssembly>
    
    The Newtonsoft one will likely already exist, but the WebGrease one won't. Check the DLL versions installed by your version of Sitecore. I am on 8.1 so my Sitecore versions were newer than those used by System.Web.Optimization
  5. In my case, I will be bundling one bundle of CSS and one bundle of JS (referenced at the body closing tag to stop JavaScript page rendering blocking). My config/definitions of the bundle is as follows.
  6. public class BundleConfig
    {
     public void Process(PipelineArgs args)
     {
      BundleConfig.RegisterBundles(BundleTable.Bundles);
     }
    
     public static void RegisterBundles(BundleCollection bundles)
     {
      bundles.Add(new ScriptBundle("~/bundles/Global").Include(
       "~/assets/plugins/bootstrap/js/bootstrap.min.js",
       "~/assets/plugins/bootstrap-hover-dropdown.min.js",
       "~/assets/plugins/back-to-top.js",
       "~/assets/plugins/jquery-placeholder/jquery.placeholder.js",
       "~/assets/js/main.js"));
    
      bundles.Add(new StyleBundle("~/Content/Global").Include(
       "~/assets/plugins/bootstrap/css/bootstrap.min.css",
       "~/assets/plugins/font-awesome/css/font-awesome.css",
       "~/assets/css/styles.css"));
     }
    }
    
    Normally with bundles you define them inside the global.asax file, however as I don't want to edit the out-of-box Sitecore file, I am hooking into the initialize pipeline (which runs on the start off the application).
  7. The patch file to register the pipeline is:
  8. <?xml version="1.0" encoding="utf-8" ?>
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
      <sitecore>
        <pipelines>
          <initialize>
            <processor type="MyProject.Helpers.BundleConfig, MyProject" />
          </initialize>
        </pipelines>
      </sitecore>
    </configuration>
    
  9. Now on the layout or master page you reference the assembly:
  10. <%@ import namespace="System.Web.Optimization" %>
    
  11. Now a runat server needs to be added to the head element
  12. <head runat="server">
    
  13. The CSS is registered in the head like so:
  14. <asp:PlaceHolder runat="server">
        <%: Styles.Render("~/Content/Global") %>
    </asp:PlaceHolder>
    
  15. The JS is registered in the page like so:
  16. <%: Scripts.Render("~/bundles/Global") %>
    
After a deploy your css and js will now be nicely bundled and minified and you should get a good scropt from YSlow!


No comments:

Post a Comment