Wednesday, June 12, 2013

Automatic Script/CSS Compression/Rollup in Umbraco MVC Views

Similar to the article about doing this in Master Page Templates but for doing so within MVC Views.

When using Umbraco you may have noticed that the Backoffice Administrative interface uses the Client Dependency Framework to roll up and compress all the different scripts and css resources into two calls.  This leads to a big improvement in responsiveness as the server doesn't need to download as much data nor complete as many requests to render a web page in the admin area.

The good new here is that you can use this same system in your actual site with very little setup.  A few simple step to configure your main site views to use the Client Dependency Framework also.

First of all add the following code to you /Views/Wec.onfig in the /configuration /system.web.webPages.razor /pages /namespaces section.

<add namespace="ClientDependency.Core" /> 
<add namespace="ClientDependency.Core.Mvc" />


Next for all of you sites master templates add the following code someplace in the HEAD block.  Note that you don't want to put this on every templates, just those that are the top level templates.  The golden rule is that every page should call this one and only once.

@Html.Raw(Html.RenderCssHere(new BasicPath("Styles", "/Css")))
@Html.Raw(Html.RenderJsHere(new BasicPath("Scripts", "/Scripts"))))

Now go through all your Views and change your Script and Css includes to the following sample blocks.

@{
  Html.RequiresCss("jquery-ui-1.8.css", "Styles", 0);
  Html.RequiresJs("jquery-1.8.3.js", "Scripts", 0);
  Html.RequiresJs("jquery-ui-1.9.js", "Scripts");
  Html.RequiresJs("http://some.other.domain/myscript.js");
}

Note that the Priority property is not required.  If set it will load those first in ascending numerical order then load any thing without a priority.  Also the system will detect duplicate inclusions of the same script/css file on the page and only include each one a single time.  You also won't see errors if a script is missing so watch for that as it can be hard to realize if you make a typo.

If you view the site now you will see two lines like this and if you inspect them they will contain all the compressed code.

<link href="/DependencyHandler.axd?s=RandmData&amp;t=Css&amp;cdv=41" type="text/css" rel="stylesheet">
<script src="/DependencyHandler.axd?s=RandmData&amp;t=Javascript&amp;cdv=41" type="text/javascript"></script>

A few other notes  This will not work when compilation/debug is set to True in the web.config.  You will need to disable debug mode to test it and also on the production environment.  Also when the code is compressed it is very hard to debug.  You will want to turn on debug mode on the development system when debugging CSS and Javascript issues or doing development.  The resources will just be loaded with individual script calls in this case.

Also once this is set up there is no reason to use minified scripts in your site anymore.  I suggest replacing them with the full versions for easier code review/editing.

To register dependencies from a Macro Script the code is a bit different.  First add this file to your App_Code directory or a precompiled DLL, then use the sample code below.  Not that this is not needed for Partial View macros.

@using ClientDependency.Core.Mvc
@using JSP.ClientDependency

Context.GetLoader()
  .RequireJs("jquery.cookie.js", "Scripts")
  .RequireCss("style.css", "Styles")
  .RequireCss("normalize.css", "styles", 0);

No comments: