Improving Google Page Speed Insights Score: Minifying & Loading JavaScript

Maybe you're new to gulp, or just want to improve your minifying task, either way, this page is for you!

Posted:

Image Source: Wikipedia

Minifying Javascript with Gulp

I know most of you will be doing this already, but, maybe you're new to gulp, or just want to improve your minifying task.

Lets install the packages that you will need:

npm install gulp gulp-sourcemaps gulp-uglify gulp-rename gulp-jshint gulp-notify gulp-include gulp-livereload --save-dev

Here is the task with some helpful comments:

gulp.task("js", function() {
    return gulp.src([
        paths.js+"/**/*.js",
        "!"+paths.js+"/**/*.min.js",
        ])
        .pipe(jshint()) // run jshin
        .pipe(jshint.reporter('jshint-stylish')) // run the jshint prettyfier
        .pipe(sourcemaps.init()) // start creating the source maps
        .pipe(uglify()) // minify stuff
        .on('error', onError) // error handling
        .pipe(rename({
            suffix: ".min" // add ".min" to the end of the filename
        }))
        .pipe(sourcemaps.write()) // finish creating the source map
        .pipe(gulp.dest(paths.js)) // created minified files at this path
        .pipe(livereload()); // refresh the page if you have the livereload browser extension installed
});

Within gulp.src we can pass an array where we can check multiple paths, in my example I have ignored any file that will end with "min.js" which could cause a loop, potentially creating something like this:

global.min.js.min.js.min.js.min.js.min.js.min.js.min.js.min.js.min.js.min.js

You may also notice instead of regular paths I use variables for them which I find very useful here is an example of my path variables:

var resources = "./build/public/resources/site";
var paths = {
    js: resources+"/js",
    css: resources+"/css",
    scss: resources+"/scss",
    images: resources+"/images",
    templates: "./build/craft/templates",
    vendor: "./build/public/resources/vendor"
};

For the sake of easy copy pasta, here is my full minifying JavaScript gulp task with a suitable watch task

var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var jshint = require('gulp-jshint');
var notify = require("gulp-notify");
var livereload = require('gulp-livereload');
var resources = "./build/public/resources/site";
var paths = {
    js: resources+"/js",
    css: resources+"/css",
    scss: resources+"/scss",
    images: resources+"/images",
    templates: "./build/craft/templates",
    vendor: "./build/public/resources/vendor"
};

// js task
gulp.task("js", function() {
    // ignore .min.js files
    return gulp.src([
        paths.js+"/**/*.js",
        "!"+paths.js+"/**/*.min.js",
        ])
        .pipe(jshint()) // run jshin
        .pipe(jshint.reporter('jshint-stylish')) // run the jshint prettyfier
        .pipe(sourcemaps.init()) // start creating the source maps
        .pipe(uglify()) // minify stuff
        .on('error', onError) // error handling
        .pipe(rename({
            suffix: ".min" // add ".min" to the end of the filename
        }))
        .pipe(sourcemaps.write()) // finish creating the source map
        .pipe(gulp.dest(paths.js)) // created minified files at this path
        .pipe(livereload()); // refresh the page 
});

// the watch task
gulp.task("watch", function () {
    livereload.listen();
    gulp.watch([
            paths.js+"/**/*.js", 
            "!"+paths.js+"/**/*.min.js"
        ], 
        ["js"]);
});

// error function
function onError(err) {
    notify.onError({
        message: 'Error: <%= err %>'
    });
    this.emit('end');
}

Loading your Javascript, Think first!

So in the rules are this:

  • As little JS in the head element as possible
  • All other JavaScript just before the closing <body> tag
  • If you use Google Tag Manager, be wary of any scripts that could be loaded by someone else who has access!

If you are trying to improve your Google Page Speed score on a pre-existing website, it can sometimes be difficult to improve even if they are very flexible, as it completely depends on how they have been setup in the first place.

If a website relies heavily on when JavaScript is loaded this could be a major problem, and you may not be able to load important "core" JavaScript files anywhere but the "head" element in order for the system to work in a reliable way. An example of this is very specific Content Management Systems (CMS), or, Ecommerce Systems (like Magento & CS-Cart) rely on JavaScript being run very early on during a page load. And elements on the page & core functionality (like the code which deals with adding a product to basket) could be loaded here, which obviously we do not want to compromise.

Loading External Scripts

Unfortunately, you probably have absolutely no control over these scripts, and, it's very likely that they will pull your Google PageSpeed Insights score down.

Lets take my site as an example, I've done literally everything I can to get a perfect score, but, Google's own script is punishing me... on GOOGLE PAGE SPEED.

98/100 on Mobile & Desktop

Scripts Loaded Through Google Tag Manager

If your website uses Google Tag Manager and there is a SEO specialist (other than yourself) working on this project with you, be very careful of any JavaScript that they may add to your site.

It's probably the case that they may not know this, but, if they add some dodgy JavaScript themselves, they could break all the JavaScript on your website!

Typical things to watch out for:

  • Some code may attempt to use jQuery or another third party script (which probably would not have not loaded by this point).
  • Some code may have been copy & pasted from another website somewhere, which may include strange characters OR more regularly, angled quotes instead of normal quotes.
  • It might be a very unoptimised piece of code, or, be flat out broken.

Basically, any JavaScript needs to be run past a developer before going into GTM.