#20 Optimizing Images
Saturday, March 2, 2019
In this article we will see how we can create a generic node script with a configuration file that we can use to optimize our images using a package called imagemin. Imagemin has an ecosystem of around 40 plugins that you can use in order to optimize an image in just about any way you would need. We will also take a look at a web based application that you can use to optimize individual images by hand while at the same time being able to see what the final ouput will look like. Lastly we will also take a look at another web application that we can use to compare images so that we can see how similar or not our optimized images are when compared with the originals.
Parts
- Part 29: Offset Pager Urls
- Part 28: Offset Pager Start
- Part 27: Mock Context Builder
- Part 26: Mock Repository
- Part 25: Mock Async
- Part 24: Picture Tag Helper
- Part 23: Img DPR Tag Helper
- Part 22: Img Responsive Tag Helper
- Part 21: Img Optimized Display
- Part 20: Img Optimization
- Part 19: Img Lazy Loading
- Part 18: Img Responsive
- Part 17: Bottom Nav
- Part 16: Main Nav Cookie
- Part 15: Main Nav Mobile
- Part 14: Main Nav Search
- Part 13: Main Nav Auth
- Part 12: Main Nav Anchors
- Part 11: Main Nav Logo
- Part 10: Search Results
- Part 9: Search Manager
- Part 8: Search Start
- Part 7: Seeding the Database
- Part 6: Domain Database
- Part 5: Emailing Exceptions
- Part 4: Mailkit
- Part 3: View Renderer
- Part 2: Upgrade to 2.1
- Part 1: Quick Start
Configuration
- WebUi
- optimizing-images.json
Instead of hard coding in things like the paths to our images we will make use of a simple json configuration file (a). For the purpose of this article we just need to know the location of the original images and where to put the optimized versions but you could of course add any other information that you might need for your particular use case.
optimizing-images.json
{
"base": "wwwroot/images/optimizing-images/",
"dest": "",
"source": "originals/"
}
Creating the optimization script
- WebUi
- image-optimization.js
Now that we have a configuration file the first thing we want to do is make sure that we are able to read it in our optimization script (b).
optimizing-images.js
const config = require("./optimizing-images.json");
console.log(config);
Now for npm
- WebUi
- package.json
Next up is both adding a few packages to our project using npm, (c), and adding a script
to the scripts object within our package.json file so that we can use node to invoke the script we
just created (d). In order to make sure that everything is working we can now use the
command npm run opt-images
in our console and we should see the contents
of our configuration file printed out.
Terminal
npm install --save-dev imagemin imagemin-mozjpeg imagemin-optipng imagemin-webp
package.json
{
...,
"scripts": {
...,
"opt-images": "node optimizing-images.js",
...
},
...,
"devDependencies": {
...,
"imagemin": "^6.0.0",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-optipng": "^6.0.0",
"imagemin-webp": "^4.1.0",
...
}
}
Optimizing images
- WebUi
- image-optimizing.js
The actual optimization of our images is pretty straight forward using the packages that we have installed (e). My motivation for using these particular plugins for imagemin is derived from the fact that they are the options used by squoosh.app which is a browser based image optimization application that uses these same image compression packages. You will note that I have decided to run the optimization function twice, once for the mozjpeg and optipng plugins and once for the webp plugin. The reason for this is when I was testing and had them all included together I would only get the output from the webp plugin.
image-optimizing.js
const path = require("path");
const imagemin = require("imagemin");
const mozjpeg = require("imagemin-mozjpeg");
const optipng = require("imagemin-optipng");
const webp = require("imagemin-webp");
const config = require("./image-optimization.json");
const source = path.resolve(__dirname, path.resolve(config.base, config.source));
const destination = path.resolve(__dirname, path.resolve(config.base, config.dest));
async function optimize(...plugins) {
await imagemin([`${source}/*.{jpeg,png}`], destination, {
plugins
});
}
optimize(mozjpeg(), optipng());
optimize(webp());
Now that our images have been optimized we can use Resemble.js , which is another web based application, to help us see what the differences between the optimized images and the originals are.