Recently I wrote about how DotNetNuke 6.1 introduces exciting new ways for developers to manage CSS and JavaScript. The release represents a significant first step in optimizing the client side impact of the framework by focusing on reducing the number of requests using dynamic page-based resource combination.
This release represents a large shift in the strategy for delivering JS and CSS resources to the client. While this is undoubtedly a net-positive to both DNN developers and users, there is also a bit of a learning curve, an adjustment period, and a few strategic changes to make along the way to insanely great performance.
File Combination
File combination is not a technique that is unique to DotNetNuke by any means. It is a common technique that is used to provide flexibility during development, and performance in production. The key to any file combination strategy is that all of a given resource type (e.g. JS or CSS) are combined with each other and output as a single file to the client’s browser.
This is the strategy that DNN 6.1 has largely adopted throughout the core framework. Let’s examine some characteristics and gotchas to be aware of when combining files.
JavaScript
When combining JS files, we’re primarily concerned with syntactical errors. What if one of the JS files we combine isn’t formatted correctly – and it ends up breaking another file that was loaded below? Now that these previously separate chunks of JavaScript logic are living in the same file – they can certainly have the opportunity to impact one another.
First, I’d like to address the root cause of this, before we talk about how to alleviate any potential problems after the fact. Always make sure you check your JavaScript for potential errors. There are plenty of tools out there to help you make sure your code is formatted properly. Of them all, I’d probably recommend JSHint. Just paste your code in there and run it through. Fix any glaring syntactical errors, and perhaps investigate any deeper recommendations the tool makes. It’s often an excellent opportunity to learn more about JavaScript.
But in a DNN world, we don’t explicitly control every JavaScript file loaded on our website (some are core, some third party and some may be custom) – so what about the case where someone makes a rogue syntactical mistake that impacts other JavaScript files when combined? Well, the underlying framework that’s being used in DNN 6.1, the Client Dependency Framework, takes care of that for us by delimiting each combined JS file with a semicolon, so as to effectively block any rogue JavaScript from impacting logic further on down the line.
CSS
So, we’re feeling pretty good about JavaScript, but what about the impacts of combining CSS? This topic is actually of more immediate importance in DNN, as most CSS files for a module or skin (module.css, skin.css) will automatically be included in this new system in DNN 6.1. The old RegisterStyleSheet method is now forwarded to the new API, so the file combination benefits for CSS happen upon upgrade. But there are two primary things I’d like to call attention to – as they may potentially have an impact on existing sites that are upgraded to DNN 6.1
The first is rogue multi-line comments. If a CSS file opens a multi-line comment and doesn’t close it out –it will start commenting out the next files CSS when combined. While adding a comment delimiter between file contents for CSS (similar to what is done with JavaScript) may be the best idea in the long run, DNN 6.1 does not include any features of this nature. So we should probably validate our CSS as much as possible to avoid any issues like this! Good thing the W3C has a handy CSS Validation Service to help us.
While the other gotchas I’ve listed have focused on syntactical issues – there is a potential strategic difference that I’d like to call attention to as well. CSS @import statements are used to help structure code when developing but to ease simplicity of file registration. For example you could create multiple CSS files, each with very focused and reusable logic, and @import them in other CSS files as appropriate. However, this example is sub-optimal from a performance perspective because the browser is still making multiple requests for these files.
In addition, @import statements are only considered valid by a browser if they are at the top of the CSS file. So if they are in the middle – they are ignored. This has significant implications when we combine the @import strategy and the file combination strategy – it could mean that @import statements are rendered ineffective depending on where they end up in the combined file.
Subsequent releases of DNN should include the ability to replace the @import statements with their actual file contents when combining files; however we were not able to get that enhancement in place for DNN 6.1.
Disabling file combination
If you run into any issues with file combination, you do have the ability to disable that specific feature altogether. This will preserve all of the other features gained by use of the new API, but will disable the file combining only.
To do so, you will need to edit values in the web.config. Specifically, find the clientDependency "fileRegistration section. Each one of the providers listed (DnnBodyProvider, etc) allows for enabling or disabling file combining. Each are enabled by default. To disable, simply change “enableCompositeFiles” to false for each provider.
Summary
While the new Client Resource Management API offers some very compelling benefits, it does also represent a very notable shift in the strategy for delivering CSS and JS content. There may be a few bumps along the road, and an adjustment period, as with any significant changes, but being aware of potential challenges and knowing your options are very important! Please let me know in the comments if you have any questions or concerns.