If you've ever done anything like run your websites through Lighthouse or any page speed insights tool you might be disappointed to realize that it's slow. Like... really slow.
One of the major drawbacks of a slow load speed is that SEO is impacted.
For my website just built with plain ol' js, css, and html, and hosted on github pages, I'm not compressing, or minifying, or concatenating any of images, html, css, or javascript. Granted, it's something I worked on right after getting out of my bootcamp. But I'm in the process of switching it over into a CMS, specifically Craft, for it's very developer friendly setup. I thought about Wordpress because I've used it for some client projects with website builders. But Craft won out.
And when moving things over, I'd come across using Gulp.js, a javascript task runner, to help make the workflow really easy, automate tedious tasks, and improve webpage speed. So let's get into it.
Installation
The installation for Gulp is fairly straightforward, where you'll have to install the gulp-cli package in your global npm so that you have access to some nice CLI tools at your disposal. I'm gonna assume you are familiar with npm and frontend development in general.
You'll run this in your terminal if you have npm installed on your machine.
npm install --global gulp-cli
If you're in a Wordpress project or another template based CMS or a non framework style frontend directory, you'll need to initialize the project first in the root directory that your template or theme or website is located in.
npm init
and can optionally run the command with the default "yes" flag that doesn't require any input from you.
npm init --y
This will create a "package.json" file in the same directory that you initialized with npm. Heads up you'll also want to include a "gitignore" file so that git knows not to save the "node_modules" folder because that thing is HUGE. Here's a link all about it.
Then in the directory that you initialized, whether it's a React, vanilla javascript, Wordpress site, or you name it, you'll run:
npm install --save-dev gulp
This just installs gulp as a developer dependency for your project.
And finally, you'll just need to create a file in the project called "gulpfile.js". This is just gonna hold the gulp tasks we'll use to automate our tasks for us.
Now what's awesome about gulp is that there's a ton of smart people that wrote awesome gulp plugins that will minify our css, js, or html and just pipe in the files that we want into the plugin.
I'm going to show you the process of using gulp on my personal site to speed up performance.
Image Compression
Basically, my page images are enormous and compressing them down will see a huge bump in performance. The gulp plugins I used for this can be installed with
npm i gulp-imagemin --save-dev
Now in our gulpfile we'll have
'use strict';
var gulp = require('gulp')
var imagemin = require('gulp-imagemin')
The "use strict" flag is a javascript convention to prevent weird quirks in the language. I'd seen it was common convention to append this in a gulpfile and just went ahead and did it.
Now to use image min we'll have the code
var baseDir = "./src"
var targetDir = "."
gulp.task('imagemin', function() {
return gulp.src(baseDir + '/assets/*')
.pipe(imagemin([
imagemin.mozjpeg({quality: 75, progressive: true}),
imagemin.optipng({optimizationLevel: 5})
]))
.pipe(gulp.dest(targetDir + '/images'))
})
The syntax above amounts to telling gulp we want to have a task named "imagemin" and input a function that does some stuff. Specifically, our function for this task will use the "gulp.src" attribute that is basically saying "Hey we want to pull out files or a file and begin doing some stuff to it." For me and my sake, I wanted gulp to look in my src folder and look for all files within an assets folder. That's what the "*" symbol is saying. When we move onto CSS and JS, then we'll need to tall gulp to only look for files of a specific type.
From there, gulp will then pipe those files into the imagemin plugin we installed. I've fed it some basic options for compression "imagemin.mozjpeg({quality: 75, progressive: true})" and "imagemin.optipng({optimizationLevel: 5})" which will just compress the png and jpeg files I input differently. The default compression options don't do all that much so be sure to tweak either with what I have or something else on the web.
Then finally the last line says to pipe the outputted compressed files into the target directory under the folder "images". This will be the nice compressed images I'll use to insert into img tags in the html.
So for your own case it should look a little something like
gulp.task('imagemin', function() {
return gulp.src([Directory where images are])
.pipe(imagemin([
imagemin.mozjpeg({quality: 75, progressive: true}),
imagemin.optipng({optimizationLevel: 5})
]))
.pipe(gulp.dest([Directory where you want outputted images to live]))
})
To run this all we have to do is type
gulp imagemin
into our command line in the project directory.
Of note, there is a plugin for gulp that allows you to output different image size dimensions for responsive viewports. For example you can output an image for small screens, medium screens, and large screens. You can take a look at that here.
CSS
Like with the above example, we'll install a css min plugin by running
npm i gulp-clean-css --save-dev
and our gulp task will look something like this
var cleanCSS = require("gulp-clean-css");
gulp.task('css', () => {
return gulp.src(baseDir + '/css/*.css')
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(gulp.dest(targetDir));
});
Then just like imagemin above, we run "gulp css" in the command line.
Just like our previous imagemin example, this one will use the same baseDir variable I specified (keeping it DRY) and will look for any files in the css directory and with a css file type. Then we pass that file into the cleanCSS plugin and then pipe it out into whatever directory we want the css to end up in.
JS
Finally, we have the option of minifying our javascript and even transpiling our ES6 into ES5 with babel. I'd found some examples of minifying javascript and others about compiling. But the nice thing about gulp piping is that I was able to just chain these processed together. For minifying your js you'll install
npm i gulp-uglify gulp-concat gulp-rename --save-dev
and if you want to transpile using babel you can intall
npm i @babel/core @babel/preset-env gulp-babel --save-dev
These working all together in my code look like
var rename = require('gulp-rename')
var babel = require('gulp-babel');
var uglify = require('gulp-uglify')
var concat = require('gulp-concat')
gulp.task('js', function() {
return gulp.src(baseDir + "/js/**/*.js")
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(concat('concat.js')) //this will concat all the files into concat.js
.pipe(gulp.dest(baseDir + "/concat")) //this will save concat.js in a temp directory defined above
.pipe(rename('index.js')) //this will rename concat.js to index.js
.pipe(uglify()) //this will uglify/minify uglify.js
.pipe(gulp.dest(targetDir + "/js"));
})
This is a little bit more of a mouthful but we just remember that the gulp.src attribute takes in where our files are and making sure that they have a ".js" filetype to them, piping them into the babel transpile plugin, then a concatenate plugin that shoves all the files into one single file. We then save the concatenated file into a temporary directory. Next we pipe the file into uglify which uglifies/minifies the javascript and finally saves that file into our desired target directory.
PHEW.
Well we round this out with a good ol' "gulp js" to compile and voila, we optimized and compressed all our big code into really small, speedy code for the web. And what do you know:
Thanks so much for sticking with me if you've made it this far. Gulp is a really cool tool that can accomplish a TON if we get the right plugins.
Top comments (7)
Gulp is awesome! I built several sites with it before jumping to gatsby.
I've been relying on gatsby/services to optimize my images for awhile, but I am not getting so many images that cloning and uploading my site was getting slow.
I decided it was time to go ahead and optimize the source images, but I went with a plain ol cli command.
I love finding articles like this because it's exactly what I need exactly this moment while I just happen to be browsing.
My weekend project was to start redoing my portfolio site. Just HTML and CSS despite working in Javascript. But Lighthouse was angry with me for not doing all the fancy unifying and whatnot even though all I needed was two files and a static web host. Now you made it look easy to add all that build step fluff to a simple site :)
Given the current popularity of Webpack (which can also perform these tasks), would you still use Gulp - pros, cons?
I think it definitely depends. For the specific purpose of working with a CMS like Wordpress or Craft I found gulp to be just less of a headache. So the main gulp pro for me is simplicity. I'm sure there's a way to configure a php or twig template file to work with webpack, but I'd figure it's not as flexible as the gulp setup I have here. I also found gulp piping to be a much easier process than configuring a webpack file.
They definitely can do very similar things for minifying css/html/js, transpiling, or preprocessing files, but adding/subtracting plugins into a gulp piping setup makes a lot more sense for me. The con for gulp is pretty much what you're getting at. If you can achieve the same result with webpack, then why bother doing more with what can be done with less.
Yes I can surely imagine that! Webpack is way more complex and it's probably overkill if all you want is minify and concatenate and not all of the other "advanced" stuff like Babel etc. Gulp is a more simple and more focused tool then.
Nice read buddy, I would never think to use Gulp to do that hehe ;), although I'm using it in my build systems (my Chrome extension).
Nice .. thanks for sharing.