Grunt is an incredible task runner that can be used to automate a wide range of web-related and non web-related tasks. For tedious tasks you perform regularly Grunt can help simplify your workflow dramatically.
One task we often find ourselves performing (over and over and over again) is the optimization and minification of images for the web. There are a ton of tools to do this kind of thing (see for example, this discussion by Addy Osmani) and fortunately helpful coders have developed Grunt plugins to do the dirty work for you.
For a detailed discussion of image optimization, see Google’s page on the topic.
In this example, we will be using two photos taken in Ithaca, NY last week. Image 1 is 577 KB and image 2 is 580 KB. Note that the images I’m showing here are the minified versions (out of respect for those with a slow connection) but if you want to play around with the full sized versions and compare your results here is image 1 and here is image 2.
1) Install Grunt’s command line interface (via node package manager)
In order to install Grunt you need to have Node.js installed (a generally painless installation). With Node installed you can install the Grunt command line interface from your command line with the command:
npm install -g grunt-cli
2) Install Grunt in your local, project directory
Now that you’ve installed the command line interface you can install Grunt in your project directory. You can again use the node package manager with the line:
npm install grunt
This installs the required Node modules (stored in the newly created ‘node_modules’ folder.
3) Install the imagemin
plugin
One final time we will take advantage of the Node.js package manager and you will install the imagemin
plugin which comes bundled with the pieces needed to optimize several different image formats:
npm install grunt-contrib-imagemin
4) Create (or steal) the code needed to run the task
The code for the task should be included at the top level of your project in a file called Gruntfile.js
. There is an example of the code at the GitHub page. I followed code from here. Your file structure should now look something like this:
And Gruntfile.js
looks like this:
module.exports = function(grunt) {
grunt.initConfig({
imagemin: {
png: {
options: {
optimizationLevel: 7
},
files: [
{
expand: true,
cwd: 'img/', //current working directory
src: ['**/*.png'],
dest: 'compressed/', // destination -- will be created
ext: '.png'
}
]
},
jpg: {
options: {
progressive: true
},
files: [
{
expand: true,
cwd: 'img/',
src: ['**/*.JPG'],
dest: 'compressed/',
ext: '.jpg'
}
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.registerTask('default', ['imagemin']);
};
Note that I set the optimization level to the max value (7).
5) Run your task
Your command window should be in the same levels as your Gruntfile.js
and to run you task you can simply type:
grunt imagemin
When we do this we get the following output in our command window:
This shows that we converted two PNG images (no JPG images) and saved a total of 807.43 KB. Given that our original files were approximately 1.1 MB combined this represents a savings of a little over 70%! Not bad for one line of code (and a little initial set-up).