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?
-
CSS files can be concatenated into one file to avoid redundant page requests.
-
JS (except jQuery) files can be concatenated into one file to avoid redundant page requests as well.
-
Concatenated files can be minified and gzipped to reduce the amount of requested data.
-
jQuery can be served from a CDN to make the library run faster than it does your own server.
-
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.
-
Download and install the latest version of node.js
-
Open a Command prompt and run the following command to install Grunt:
npm install -g grunt-cli
-
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:
-
Move all your CSS and JS files (which should be processed by Grunt) to the appropriate folders "src", like this:
-
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"
}
}
-
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.
-
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!