Bundling css and js files

From Sense/Net Wiki
Jump to: navigation, search
  •  
  •  
  •  
  •  
  • 100%
  • 6.1
  • Enterprise
  • Community
  • Planned

Overview

By default, Sense/Net bundles separate javascript and css files into a single css and a single js file and minifies them using the Microsoft Ajax Minifier. This guarantees that Sense/Net pages are loaded in client browsers with high speed, since the number of requests sent to the Sense/Net server is reduced dramatically. This allows for more responsiveness and better user experience.

Details

Pages may include references to css and javascript files. When loading a page the browser will send multiple requests to the server: a request is sent to every individual css and javascript file. Depending on the number of css and javascript files included, page loading may become significantly slower. To circumvent this Sense/Net bundles all included css and javascript files into a single css and javascript file, thus minimizing the number of requests sent to the Sense/Net server when loading a page.

Usage

The bundling process is fully transparent and automatic. The only rule you will need to remember is to use the standard Sense/Net controls to include css and javascript files, as discussed in The Skin System - for Portal builders:

<!-- including css in a Sense/Net page - all css will be included with a single request -->
<sn:CssRequest Path="$skin/styles/style1.css" ID="style1" runat="server" />
<sn:CssRequest Path="$skin/styles/style2.css" ID="style2" runat="server" />
 
<!-- including javascripts in a Sense/Net page - all scripts will be included with a single request -->
<sn:ScriptRequest Path="$skin/scripts/sn/script1.js" ID="request1" runat="server" />
<sn:ScriptRequest Path="$skin/scripts/sn/sctipt2.js" ID="request2" runat="server" />

By default bundling of css and js files is turned on, so only a single request will be sent for all included javascripts and the same applies to css files.

Configuration

You can switch off javascript and css bundling in the web.config.

  <sensenet>
    <portalSettings>
      <add key="AllowCssBundling" value="true" />
      <add key="AllowJsBundling" value="true" />
      ...

It is possible to make exceptions if bundling is enabled. This means you can make a 'blacklist' of js and css folders or individual files that you do not want to be bundled.

  <sensenet>
    <portalSettings>
      <add key="JsBundlingBlacklist" value="/Root/Global/scripts/yourfolder/;/Root/Global/scripts/plugins/yourplugin/yourfile.js" />
      <add key="CssBundlingBlacklist" value="" />
      ...

You can also disable bundling for individual CSS files in html:

<sn:CssRequest Path="$skin/styles/style1.css" AllowBundling="false" ID="style1" runat="server" />

How it works

When a page is requested the referenced css and javascript files are bundled into a single file (bundle). This operation is carried out on a background-thread, so page load times are not affected by creating bundles. The name of the created bundle will contain a hashcode of the included js/css paths and the date of generation. After the bundle has been created only a single js/css file reference will be rendered into the page. These bundles will include all css and javascript content that were referenced by the page:

<link href="/sn-bundles/5466a99013755e602a1aa7eeb30adfa5_2012.05.11_14.48.35" rel="stylesheet" type="text/css" media="all" />
<script src="/sn-bundles/5d1986f5991b6d8d7ef8dd80af38e460_2012.05.11_14.48.35" type="text/javascript"></script>

When a bundle is created it is immediately put into the cache. Caching of bundles ensures that multiple requests to pages including the same javascript/css files will not invoke a lengthy bundling operation, the already existing bundle is retrieved from the cache and served to the client. Modifying/deleting/renaming the bundled css and javascript files invokes cache invalidation, so whenever a referenced file changes all corresponding bundles will be regenerated.

New since Sense/Net 6.3
  • Data URIs. Small image files will be incorporated into CSS code through the use of data URIs in order to reduce the number of HTTP requests.
  • Most of the built-in ASP.NET script resources (ScriptResource.axd and WebResource.axd) will be added to the bundle. At the time of this writing, Sense/Net does this by sending HTTP requests to itself to get the content of these resources.

Performance considerations

The bundling support for Sense/Net was implemented with important performance considerations in mind, in order to minimize the processing time spent on the server.

We have done this to ensure that this feature is as performant and fast as possible.

Advanced details for developers and experts
  • The Sense/Net server side will always set the Last-Modified HTTP header for all bundles served. This will allow clients to send If-Modified-Since headers for their subsequent requests to the same bundle. When this happens, Sense/Net will send a HTTP 304 "Not modified" response. This saves a lot of bandwidth and reduces the CPU time required on the server for processing such requests.
  • Automatic compression. If the client sends a HTTP Accept-Encoding header and it accepts gzip and deflate compression, Sense/Net will automatically send the bundled content using the specified comression method.
  • Caching support. Sense/Net will cache its generated bundles on the server side (as mentioned above). In addition to this, every proxy server and client is also expected to cache them.

CSS relative URLs and @import directives

Sense/Net will automatically replace all relative URLs in your CSS files to absolute URLs when it bundles them together. It also supports the CSS @import directives when bundling CSS files. Local CSS files which reside in the Content Repository will be automatically recursively expanded into the bundled CSS code, and non-local imports will be put to the top of the CSS. (As per the CSS standard, @import directives may only appear at the top of a CSS document.)

CSS media types

The CssRequest control also allows you to set the media type of the given CSS files. (This is rendered into the 'media' attribute of the resulting link tag.) Sense/Net will create one bundle per CSS media type, thus giving you the ability to utilize the power of bundling and the ability to distinguish your CSS by media types too.

Error handling

If your CSS or Javascript code contains errors which prevent them from being parsed by the Microsoft Ajax minifier, the bundling will still happen, however in a much more primitive way. The code files will be concatenated but not minified and useful comments will be added that help portal builders and developers to identify the problem and fix it. In this case, Sense/Net will append the errors to the end of the bundled documents.

Limitations of the technology

At the moment, Sense/Net CSS and Javascript bundling doesn't support local paths to CSS or Javascript files which reside outside of the Content Repository. It does support absolute URLs though. This behaviour may change in a future version.

Versions before Sense/Net 6.3 used to be incapable of incorporating the ScriptResource.axd and WebResource.axd script references into their bundles. This has been fixed in the 6.3 release.

Do not use relative paths in your Javascript files when you use bundling. There is no easy way to reliably replace all of them, so Sense/Net does not have such logic in place. Relative paths in Javascript will probably be broken by the bundling functionality. Note that relative paths in CSS are easily detectable so this limitation does not affect CSS bundles.

Example/Tutorials

There are no examples for this article.

Related links

References