Optimizing a website's performance with Grunt

   —   

Don’t you hate it when someone or something wastes your time? I guess everyone does – especially when it comes to websites. The longer it takes for your website to load, the higher the chances are that a visitor will leave before your page is displayed. Before you know it, you’ve lost a potential customer. Over the past several days, we’ve been optimizing CSS and JavaScript files with Grunt to improve the performance of the Kentico DevNet website. The final result is that the website is 33% faster than before. So far, so good. In this article, I will discuss how to speed up your website by integrating Grunt into your development process with Kentico.

Grunt is a JavaScript task runner that automates repetitive tasks like minification, compilation, linting, and so forth. So while you are writing your CSS or JS code, Grunt automatically generates deployment ready files. If you haven't used Grunt before, be sure to check out the Getting Started guide.

Performance enhancements

Several months ago, I was reviewing tons of web projects and assessing their quality from a front-end implementation point of view. One of the most common issues was that many of these websites had serious performance problems. I found JavaScript and CSS files that were linked to the website's head section, and to make matters worse, the code wasn't minified and concatenated. It looked just like this:

<head> <!-- CSS Files --> <link type="text/css" rel="stylesheet" href="/App_Themes/Site/main.css" /> <link type="text/css" rel="stylesheet" href="/App_Themes/Site/slider.css" /> <!-- JS Files --> <script type="text/javascript" src="/CMSScripts/Custom/jquery.js"></script> <script type="text/javascript" src="/CMSScripts/Custom/modernizr.js"></script> <script type="text/javascript" src="/CMSScripts/Custom/slider.js"></script> <script type="text/javascript" src="/CMSScripts/Custom/main.js"></script> </head>

What could be improved with use of Grunt?

  1. CSS files can be concatenated into one file to avoid redundant page requests.
  2. JS (except jQuery) files can be concatenated into one file to avoid redundant page requests as well.
  3. Concatenated files can be minified and gzipped to reduce the amount of requested data.
  4. jQuery can be served from a CDN to make the library run faster than it does your own server.
  5. You can load JS files at the bottom of a page to not block rendering the website.

So the improved result would look like:

<head> <link type="text/css" rel="stylesheet" href="/Site/assets/css/concatenated.min.css" /> </head> <html> ... <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript" src="/Site/assets/js/concatenated.min.js"></script> </html>

As you can see, the CSS and JS files have been moved into the /Site/assets/ folder. This occurs because Grunt pushes you to store files in a unified location. At the end of the day, this will make your project easier to maintain. Keep on reading...

How to integrate Grunt with Kentico

We’ve been thinking hard (and smart) about the best way to integrate Grunt within Kentico. We wanted to facilitate the set up process for new projects and also make it easy to work with CSS and JS files within a team of developers. In the following steps, I will describe how you can install Grunt, set up the appropriate folder structure with CSS and JS files, and run Grunt to generate concatenated and minified files.

  1. Download and install the latest version of node.js

  2. Open a Command prompt and run the following command to install Grunt:

    npm install -g grunt-cli
  3. As mentioned above, when you have Grunt installed, you must set up a new folder structure. Navigate to your Kentico installation folder (e.g. C:\inetpub\wwwroot\Kentico\CMS). If you’ve already created a new site in the Kentico Administration, there should be a folder located there that is named in concordance with the site’s name. I have named the site "Site" so the folder’s name is "Site" as well. With the above in mind, go ahead and create the following folder structure:

  4. Move all your CSS and JS files (which should be processed by Grunt) to the appropriate folders "src", like this:

  5. Once you’ve done this, you need to set up the necessary Gruntfile.js and package.json for your project. I have prepared sample files that will perform the concatenation and minification of your code for you. Place them into your project:

    • Gruntfile.js:
      module.exports = function(grunt) { grunt.initConfig({ cssmin: { css: { files: { 'assets/css/concatenated.min.css': 'assets/css/src/*.css' } } }, uglify: { js: { files: { 'assets/js/concatenated.min.js': 'assets/js/src/*.js' } } } }); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.task.registerTask('default', ['cssmin', 'uglify']); }
    • package.json:
      { "name": "site", "version": "0.0.1", "author": "Milan Kacurak", "devDependencies": { "grunt-contrib-cssmin": "^0.10.0", "grunt-contrib-uglify": "~0.4.0" } }
  6. Before you run Grunt you need to obtain the necessary node modules. Open Command propmt and navigate to your project folder (e.g. cd C:\inetpub\wwwroot\Kentico\CMS\Site). Then run following command:

    npm install
    Grunt will automatically download the node modules defined in the package.json file.

  7. Finally, you can run Grunt to process CSS and JS files. Run the following command:

    grunt

    Grunt will take files from the src folders and generate concatenated and minified files.

And… that’s it! You can now link generated files to your website as I have described above.

The above is just a simple example which demonstrates how we can use Grunt in Kentico projects. Of course, we use more node modules like watch, less, csslint, jshint, autoprefixer or dev-update and complex logic in the Gruntfile.js for Kentico DevNet.

Feel free to leave a comment or contact me directly if you’d like more information. Also, please let us know how the process of integrating Grunt to Kentico went.

Tip: In Visual Studio you can use the Grunt Launcher extension to process your files without the need of a Command prompt.

Thanks for stopping by!

Share this article on   LinkedIn

Milan Kačurák

My intention is to give you practical information about web site development in Kentico. <a href="http://kacurak.com/">Find more information about me on my personal web site</a>.

Comments

Milan Kacurak commented on

Hi David,
thank you for your comment. You are right there is no integration from technical (or back-end) point of view. Purpose of this article is not to provide you with tutorial on how to run Grunt within Kentico Portal Engine or whatever...

This article is more about process. It is about the way you can use tool within Kentico enviroment which is commonly used by web developers on different platforms. We can complaint Kentico does not support concatenation but we also can think about how to effectively integrate existing tools into our processes to achieve our goals.

I can prove the solution I describe above works prefectly in a team development. We developed several web sites including the new Partner Portal with this approach. It is an effective and low cost solution which brings more possibilities to your Kentico front-end development.

David Walsh commented on

I don't see much in the way of integration here. Grunt runs entirely separate from Kentico.

Ideally it shouldn't even be necessary to use Grunt. Kentico supports minification out of the box (see https://docs.kentico.com/display/K8/Using+code+minification+and+compression). It would be great if it supported concatenation too.

Milan Kacurak commented on

Hi Joe, thank you for your comment and very interesting question. In my opinion this approach could be good if the js/css code is used only on small amount of pages or on pages which have small amount of page visits. The reason is that there is a quite little chance that users visit such pages. Majority of your users get concatenated js/css code as a single file. On some specific page you can serve them some additional code.
In general concatenating js/css files ensures that users get all your js/css code in a single request on a first page load and the code gets cached by their browser. Every page request means additional time for the page load. So even if your js/css files are very small it could take several hundred miliseconds more to load the page if you link them separately than if you link them as a single file.
Anyway, keep in mind that your approach to performace should always depend on your specific situation which could be influenced by technology, client, budget, processes, etc. :)

Joe commented on

Hi Milan, excelllent article. I have used grunt in the past of minifying my css and js files but I never concatinated them for the simple reason that not all the css/js is used on all pages. Do you think this is a good approach?

Milan Kacurak commented on

Hi Ryan,
Regrettably, your site is not available... However, I would say every website can be optimized with Grunt. Just contact me if you need help. Good luck!

Ryan Parnham commented on

Hi there I wonder if my website <a href="http://www.the-pillows.com.au">the-pillows</a> performance can be optimized with , it appears promising.