Improving Google PageSpeed Insights Score: Optimising decorative template images

Posted:

There are a couple of methods that you will have to consider when it comes to optimising a website's images.

  1. Decorative images for your website's templates (that live outside the CMS)
  2. Compressing images served by your CMS (new blog post coming soon)

If you are not familiar with gulp, or, your website doesn't have many files that need compressing running them through a service like TinyPNG might be a good solution for you, the compression rates are high, and, appears to retain the quality. BUT, it's not lossless, as in that, quality will be lost.

Dealing with compressing images in gulp is initially a little tricky to get your head around, and, the documentation on the face of it is pretty rubbish, especially for a newbie, and, the community isn't very active which is erm... helpful.

If you want to cut right to the chase take a look at my boilerplate called "Big Juicy Sass" repo on github for a generic CraftCMS setup & an up to date gulpfile.js.

It appears that there is only really one majorly used Gulp plugin called gulp-imagemin.

The problem with this plugin is that compression it MINimal. As they use a set of lossless optimisers:

Just so there is some decent settings documented for a standard task with up to date code here you go:

.pipe(imagemin({
    progressive: true,
    interlaced: true,
    optimizationLevel: 4,
    svgoPlugins: [{removeViewBox: false}],
}))

Best method to compress PNGs

I have found there are some alternative plugins available which you can pass to imagemin. I have tried all the PNG options, the compression rates unfortunately aren't as good as I would have hoped. I tested them all with the same png file, quite large, no transparency, original size = 1.4MB

Here are the results:

TinyPNG.com still managed to get it to 413KB

So basically:

  • If the quality cannot be compromised in the slightest, the default imagemin plugin "optipng" is the best method - Which can save up to 35%
  • If that is not a problem pngquant or tinypng might be more suitable, (it doesn't look that bad, but sometimes artefacts are noticeable below 75%).

For the sake of saving and extra 10% for TinyPNGs version (which probably has some sort of dynamic quality setting magic), I think it's probably best to stick with pngquant. Though if you would like to use TinyPNG read on in the following section.

TinyPNG with Gulp

TinyPNG actually have a Developer API where you can sign up and get a free API which allows you to compress 500 images per month! And, you can set this up with a gulp task using gulp-tinypng-compress which will use your API Key. Additionally Kraken.io have an identical API solution with their own gulp plugin too.

How to cheat TinyPNG's API

If you want to be a dirty pirate, I found that some guy has made a gulp plugin gulp-tinypng-nokey which submits them to the TinyPNG home page! Fantastic! What an innovative way to cheat the system @paper. Doing this might put TinyPNG related meta data in your images, so you could run a task or a plugin after which would strip out any image meta data (if you wanted to be careful).

Anyway, here is an example of how you can do it the legit way with gulp-tinypng-compress:

gulp.task('tinypng', function () {
    gulp.src([
        "./resources/images/**/*.{jpg,jpeg,png}",
    ])
    .pipe(tinypng({
        key:"getyourownkey_youthief",
        log:true
    }))
    .pipe(gulp.dest("./resources/images"));
});

Best method to compress JPGs

Just like above I've tested all the jpg plugins too! My test image could be an adequate banner in a real world situation. 1920x600 px, 100% jpg quality filesize = 1.2MB

The results:

Here is a code example of how to use what seems to be the best method (jpeg-recompress):

gulp.task("imagemin", function(){
    return gulp.src("./resources/images/**/*")
        .pipe(imagemin([
            imageminJpegRecompress({
                progressive: true,
                max: 80,
                min: 70
            })
        ]))
        .pipe(gulp.dest("./resources/images"));
});

The Full Gulp imagemin task

In order to use a custom plugin, with the built in ones, you will need to define them again, otherwise it seems to ignore them. At a minimum you would need to install these gulp plugins:

npm install gulp gulp-imagemin imagemin-jpeg-recompress imagemin-pngquant --save-dev

The task in full:

const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const imageminJpegRecompress = require('imagemin-jpeg-recompress');
const imageminPngquant = require('imagemin-pngquant');

gulp.task("imagemin", function(){
    return gulp.src("./resources/images/**/*")
        .pipe(imagemin([
            imagemin.gifsicle({interlaced: true}),
            imageminJpegRecompress({
                progressive: true,
                max: 80,
                min: 70
            }),
            imageminPngquant({quality: '75-85'}),
            imagemin.svgo({plugins: [{removeViewBox: false}]})
        ]))
        .pipe(gulp.dest("./resources/images"));
});

Compressing images served by your CMS

Just like there are with Gulp, there are normally methods to compress images within almost any CMS system! Obviously some are better than others. In an up coming blog post, I will be discussing how we can optimise these even further if you are working with CraftCMS.