10.0.x
541 201 9965 Email Website
Contents
:
Search:

Home > Development Notes > Client Resource Manager

Client Resource Manager

Overview

The client resource manager is a framework to centrally manage client-side resources like stylesheets and JavaScript from AspDotNetStorefront code. It's focused on improving client-side rendering performance through bundling, minification, relocation, and inline rendering.

In order to use the framework, all code and content must be written with the new API's. Once that's done, you can update the site configuration to enable the new features. If any content or code is not updated, it's best to leave client resource management disabled, otherwise hard to find client-side errors may occur.

Configuration

AppSettings.config - EnableBundlingAndMinification If you enable this setting, any local CSS and JavaScript references registered with the framework will be minified and bundled into as few requests as possible. If you disable this setting, all registered references will be included as defined.

AppConfig - ClientResources.Script.DeferredRenderingEnabled If you enable this setting, and registered JavaScript will be relocated to the bottom of the <body> tag. If you disable this setting, all registered JavaScript will be written out at the point it was defined.

API

The API exposes five operations. All of these API's are available from code, but some are also exposed to Razor, XML Packages, and parsed content (topics and product/entity descriptions).

API Code Razor XML Package Content
Register inline JavaScript
Register JavaScript bundle
Register JavaScript reference
Register CSS bundle
Render relocated JavaScript  

JavaScript registrations allow you to specify any other scripts the registered script depends on. When deferred rendering is enabled, the client resource manager will ensure that the relocated scripts are written out in an order that guarantees those relationships. To identify script references for a dependency, use the script's URL. To identify an inline script for a dependency, provide a value for the name parameter when registering the inline script and use that name in the dependency list.

AspDotNetStorefront ships with common script paths defined in the AspDotNetStorefront.ClientResource.ScriptPaths, AspDotNetStorefront.ClientResource.ScriptBundlePaths, and AspDotNetStorefront.ClientResource.InlineScripts classes. Use these whenever possible to enhance the reliability and portability of your code. You can call the aspdnsf:GetNamedScriptBundlePath() and aspdnsf:GetNamedScriptPath() XSLT functions to get a similar benefit for XSLT code.

You can (and should) use the ASP.NET root operator (~) when registering script bundles and references that are hosted on your site.

All registrations done in C# or Visual Basic are performed using the AspDotNetStorefront.ClientResource.IClientScriptRegistry service. Registrations can be done directly against the service, but there are several extension methods in the AspDotNetStorefront.ClientResource namespace that drastically simplify registrations.

Each registration returns a string that contains any artifacts of the registration that need to be written to the response at the point of registration. The return string must always be written out to the response.

The site template must contain a call to render relocated JavaScript at the <body> close. If this is not done, rendered JavaScript may not render on the page depending on configuration.

CSS registrations do not participate in deferred rendering. They always render at the location they are defined.

Register Inline JavaScript

You can register inline JavaScript that will be rendered directly on the page. When deferred rendering is enabled, this JavaScript will be relocated to the bottom of the <body>. Inline JavaScript will never be bundled or minified.

Inline script registrations require a content paramter that contains the inline script to be rendered. If the optional addScriptTag paramter is false, the content must contain the <script> tag wrapping the script. In XSLT registrations, the content is provided by the <script> node, so the addScriptTag parameter is not available.

Inline script registrations accept an optional name parameter. If you provide a value for this parameter, you can reference the inline script as a dependency when registering other scripts.

Inline script registrations accept an optional dependencies parameter. If you provide a value for this parameter and deferred rendering is enabled, the client resource manager will ensure those scripts are rendered before the registered script. You can (and should) use the ASP.NET root operator (~) when specifying URL's for dependencies.

C#

using AspDotNetStorefront.ClientResource;
 
var clientScriptRegistry = DependencyResolver.Current.GetService<IClientScriptRegistry>();
 
var result = clientScriptRegistry.RegisterInlineScript(
  HttpContext,
  @"<script type="text/javascript">
    adnsf$('body').append(Date());
  </script>",
  name: "AppendDateToBody",
  dependencies: new[]
  {
    ScriptPaths.JQuery.AdnsfAlias,
  });
 
Response.Write(result);

Razor

@Html.RegisterInlineScript(
  @<script type="text/javascript">
    adnsf$('body').append(Date());
  </script>,
  name: "AppendDateToBody",
  dependencies: new[]
  {
    ScriptPaths.JQuery.AdnsfAlias,
  })

XML Packages

<xsl:variable name="appendDateToBodyScript">
  <script>
      adnsf$('body').append(Date());
  </script>
  <name>AppendDateToBody</name>
  <dependency>
    <xsl:value-of select="aspdnsf:GetNamedScriptPath('JQuery.AdnsfAlias')" />
  </dependency>
</xsl:variable>
 
<xsl:value-of select="aspdnsf:RegisterInlineScript($appendDateToBodyScript)" disable-output-escaping="yes" />

Content

<script aspdnsf-registered="true" aspdnsf-registered-name="AppendDateToBody" aspdnsf-registered-dependencies="~/scripts/jquery.adnsfalias.js">
  adnsf$('body').append(Date());
</script> 

Register JavaScript Bundle

A JavaScript bundle is a collection of one or more JavaScript files hosted on the site. When bundling and minification is enabled, files are grouped together under a common bundle URL and minified to improve client render performance.

How bundles are written depends on configurations:

Bundling and Minification Deferred Rendering Result
Disabled Disabled Each individual script reference in the bundle is written out at the point it was registered.
Enabled Disabled Each call to the bundle registration renders out a bundle of just the references in that one registration at the point it was registered.
Disabled Enabled Each individual script reference in the bundle is written out at the end of the <body>.
Enabled Enabled All registrations with the same bundle URL are written as a single bundle at the end of the <body>.

Script bundle registrations take a required bundleUrl parameter that indicates the URL the bundle will be accessed at. This is the key that scripts will be grouped together under when both deferred rendering and bundling and minification are enabled. If just bundling and minification is enabled, each registered bundle will be written out with a unique bundle URL derived from the bundleUrl parameter. You can (and should) use the ASP.NET root operator (~) when specifying this URL.

Script bundle registrations take a required urls parameter that lists the local script references that are to be included in the bundle. Each URL in the list is registered with an implicit dependency on the one before it, which will help ensure they're rendered out in the order provided. You can (and should) use the ASP.NET root operator (~) when specifying these URL's.

Script bundle registrations accept an optional dependencies parameter. If you provide a value for this parameter and deferred rendering is enabled, the client resource manager will ensure those scripts are rendered before the bundle. You can (and should) use the ASP.NET root operator (~) when specifying URL's for dependencies.

C#

using AspDotNetStorefront.ClientResource;
 
var clientScriptRegistry = DependencyResolver.Current.GetService<IClientScriptRegistry>();
 
var result = clientScriptRegistry.RegisterScriptBundle(
  HttpContext,
  "~/scripts/custom_bundle",
  new[]
  {
    "~/scripts/custom_script_1.js",
    "~/scripts/custom_script_2.js",
    "~/scripts/custom_script_3.js",
  },
  dependencies: new[]
  {
    ScriptPaths.JQuery.AdnsfAlias,
  });
 
Response.Write(result);

Razor

@Html.RegisterScriptBundle(
    "~/scripts/custom_bundle",
  new[]
  {
    "~/scripts/custom_script_1.js",
    "~/scripts/custom_script_2.js",
    "~/scripts/custom_script_3.js",
  },
  dependencies: new[]
  {
    ScriptPaths.JQuery.AdnsfAlias,
  })

XML Packages

<xsl:variable name="customScriptBundle">
  <bundleUrl>~/scripts/custom_bundle</bundleUrl>
  <url>"~/scripts/custom_script_1.js"</url>
  <url>"~/scripts/custom_script_2.js"</url>
  <url>"~/scripts/custom_script_3.js"</url>
  <dependency>
    <xsl:value-of select="aspdnsf:GetNamedScriptPath('JQuery.AdnsfAlias')" />
  </dependency>
</xsl:variable>
 
<xsl:value-of select="aspdnsf:RegisterScriptBundle($customScriptBundle)" disable-output-escaping="yes" />

Content

<script src="~/scripts/custom_script_1.js" aspdnsf-registered="true" aspdnsf-registered-bundle="/test/custom_bundle" aspdnsf-registered-dependencies="~/scripts/jquery.adnsfalias.js"></script>
<script src="~/scripts/custom_script_2.js" aspdnsf-registered="true" aspdnsf-registered-bundle="/test/custom_bundle" aspdnsf-registered-dependencies="~/scripts/jquery.adnsfalias.js"></script>
<script src="~/scripts/custom_script_3.js" aspdnsf-registered="true" aspdnsf-registered-bundle="/test/custom_bundle" aspdnsf-registered-dependencies="~/scripts/jquery.adnsfalias.js"></script>

Register JavaScript Reference

A JavaScript reference is a link to an external JavaScript. While they can be used for scripts hosted on the site, bundles are a better solution for those. Script references are never bundled or minified, but they will be relocated to the <body> close if deferred rendering is enabled.

Script references registrations take a required url parameter. This is the URL of the script to be included on the page.

Script references registrations accept an optional async parameter. Set this to true to render an async attribute on the generated <script> tag.

Script references registrations accept an optional dependencies parameter. If you provide a value for this parameter and deferred rendering is enabled, the client resource manager will ensure those scripts are rendered before the bundle. You can (and should) use the ASP.NET root operator (~) when specifying URL's for dependencies.

C#

using AspDotNetStorefront.ClientResource;
 
var clientScriptRegistry = DependencyResolver.Current.GetService<IClientScriptRegistry>();
 
var result = clientScriptRegistry.RegisterScriptReference(
  HttpContext,
  "https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/3.0.1/isotope.pkgd.min.js",
  dependencies: new[]
  {
    ScriptPaths.JQuery,
  });
 
Response.Write(result);

Razor

@Html.RegisterScriptReference(
    "https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/3.0.1/isotope.pkgd.min.js",
  dependencies: new[]
  {
    ScriptPaths.JQuery,
  });

Content

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/3.0.1/isotope.pkgd.min.js" aspdnsf-registered="true" aspdnsf-registered-dependencies="~/scripts/jquery.js"></script>

Register CSS bundle

A CSS bundle is a collection of one or more CSS stylesheets files hosted on the site. When bundling and minification is enabled, files are grouped together under a common bundle URL and minified to improve client render performance.

CSS bundle registrations take a required bundlePath parameter that indicates the URL the bundle will be accessed at. When bundling and minification is enabled, the stylesheets in the bundle will be grouped into this one URL and minified. When bundling and minification is disabled, each stylesheet will be rendered as it's own <link> tag. You can (and should) use the ASP.NET root operator (~) when specifying this URL.

CSS bundle registrations take a required filePaths parameter that lists the local stylesheet references that are to be included in the bundle. The URL's in the list will be rendered in the order provided. You can (and should) use the ASP.NET root operator (~) when specifying these URL's.

CSS bundle registrations accept an optional inline paramter. If this parameter is true, the contents of the bundle will be rendered inline in the HTML instead of as <link>'s to the stylesheets. Be careful when using this parameter, as it changes the relative paths of any external resources defined in the referenced stylesheets.

C#

using AspDotNetStorefront.ClientResource;
 
var bundledResourceProvider = DependencyResolver.Current.GetService<IBundledResourceProvider>();
 
var result = bundledResourceProvider.RenderStyleBundle(
  "~/css/custom_bundle",
  new[]
    {
    "~/css/custom_stylesheet_1.css",
    "~/css/custom_stylesheet_2.css",
    "~/css/custom_stylesheet_3.css",
    });
 
Response.Write(result);

Razor

@Html.RenderStyleBundle(
    "~/css/custom_bundle",
    new[]
    {
    "~/css/custom_stylesheet_1.css",
    "~/css/custom_stylesheet_2.css",
    "~/css/custom_stylesheet_3.css",
    })

Render Relocated JavaScript

When deferred rendering is enabled, the template must call a method to indicate where the relocated content should be rendered. This should be just before the <body> close tag, after any possible page content.

C#

using AspDotNetStorefront.ClientResource;
 
var clientScriptRegistry = DependencyResolver.Current.GetService<IClientScriptRegistry>();
 
var result = clientScriptRegistry.RenderDeferredResources(HttpContext);
 
Response.Write(result);

Razor

@Html.RenderDeferredScripts()


Actions
Print This Article
Bookmark
Email This Article
Previous Article
Next Article

Was this page helpful?YesNo