Make your builds quicker with Gulp 4
Tags: gulpjs, node, webdev, performance
Published: 2019-03-02 11:02:21

---
title: Make your builds quicker with Gulp 4
published: true
description: Learn how to parallelize your tasks with Gulp 4
tags: gulp.js, node, webdev, performance
cover_image: https://thepracticaldev.s3.amazonaws.com/i/qpa94jv7iky7trx6jqw8.jpeg
---

Gulp version 4 is out! The migration is pretty straight forward and involves minimum breaking changes while bringing one very useful feature: to be able to parallelize tasks.

## Upgrading from 3 to 4

You can follow one of the most popular [Medium post](https://codeburst.io/switching-to-gulp-4-0-271ae63530c0) on making the transition successfuly.

Sam also wrote on his recipe on how to make the transition a breeze.

{% link https://dev.to/samhermes/upgrading-from-gulp-3-to-4-329a %}

## Compressing images with Gulp 3

Before Gulp 4, this is what you might have done to compress images.

```javascript
const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const webp = require("gulp-webp");

gulp.task("pictures", function() {
  return gulp.src("src/img/**/*.{jpg,jpeg,png,svg}")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("webp", function() {
  return gulp.src("src/img/**/*.{jpg,jpeg,png}")
    .pipe(webp())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("img", ["pictures", "webp"]);
```

Which means

> Compress my jpeg, png and svg files one by one, and wait before they are all compressed before converting them into webp.

Which is fine, but the main caveat is that your `picture` tasks will have to process all your images one by one. 

If we think about it, we could split our process by file types: `png`, `jpeg`, `svg`. This is possible because [gulp-imagemin](https://www.npmjs.com/package/gulp-imagemin) uses different libraries to compress images ([SVGO](https://www.npmjs.com/package/svgo), [PNGQuant](https://www.npmjs.com/package/pngquant), [JPEGTran](https://www.npmjs.com/package/jpegtran)).

## Compressing images with Gulp 4

First let us keep the same algorithm, and use the new [`gulp.series()`](https://gulpjs.com/docs/en/api/series) method.

```javascript
const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const webp = require("gulp-webp");

gulp.task("picture", function() {
  return gulp.src("src/img/**/*.{png,jpg,jpeg,svg}")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("webp", function() {
  return gulp.src("src/img/**/*.{png,jpg,jpeg}")
    .pipe(webp())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("img", gulp.series("picture", "webp"));
```

![Doing the same, but with modern methods](https://media.giphy.com/media/C6JQPEUsZUyVq/giphy.gif)

If you run `gulp img` on your console, you will have the same output. Now we use the latest Gulp 4 features, pretty straight forward migration!

Let us split up our `picture` task.


```javascript
const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const webp = require("gulp-webp");

gulp.task("png", function() {
  return gulp.src("src/img/**/*.png")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("jpg", function() {
  return gulp.src("src/img/**/*.{jpg,jpeg}")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("svg", function() {
  return gulp.src("src/img/**/*.svg")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("webp", function() {
  return gulp.src("src/img/**/*.{png,jpg,jpeg}")
    .pipe(webp())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("img", gulp.series("png", "jpg", "svg", "webp"));
```

Again, nothing changed, only making it more easier for what comes next.

Now the fun part: let us make the 3 first tasks run in parallel.

```javascript
const gulp = require("gulp");
const imagemin = require("gulp-imagemin");
const webp = require("gulp-webp");

gulp.task("png", function() {
  return gulp.src("src/img/**/*.png")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("jpg", function() {
  return gulp.src("src/img/**/*.{jpg,jpeg}")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("svg", function() {
  return gulp.src("src/img/**/*.svg")
    .pipe(imagemin())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("webp", function() {
  return gulp.src("src/img/**/*.{png,jpg,jpeg}")
    .pipe(webp())
    .pipe(gulp.dest("dist/img"));
});

gulp.task("img", gulp.series(gulp.parallel("png", "jpg", "svg"), "webp"));
```

Which means:

> Compress all the png, jpg and svg files in whatever order you want, but wait for all before starting converting them into webp.

Using the new [`gulp.parallel()`](https://gulpjs.com/docs/en/api/parallel), this is a piece of cake to perform parallelized tasks!

## Going further

Now this is better, but there is still one little thing that bugs me. If you noticed, this is the blob used for our pictures:

```javascript
".{png,jpg,jpeg,svg}"
```

But the webp blob is missing the svg:

```javascript
".{png,jpg,jpeg}"
```

I did this on purpose because I do not want to convert my SVG files into WebP: they are perfect to respond to responsiveness while keeping a high quality so I do not want to loose this feature.

This also means our that `webp` task does not have to wait before svg to finish to be compressed. So we could add another optimization layer like following.

```javascript
gulp.task('picture', gulp.parallel('png', 'jpg'));

gulp.task('img', gulp.parallel(gulp.series('picture', 'webp'), 'svg');
```

Which means:

> Compress SVG files in the same time as compressing jpg and png files with webp waiting for jpg and png files before converting them into webp.

## Conclusion

I love Gulp for its great user experience. Building complex bundling logic is just so neat and clear. 

Check out [the documentation](https://gulpjs.com/docs/en/getting-started/quick-start) if you want to know more about gulp and all its features, including watching file changes and perform tasks as you update a file, and plenty more.

Gulp also supports modern Javascript notation, so you might want to write your fancy tasks like:

```javascript
const { src, dest, series, parallel } = require("gulp");
const imagemin = require("gulp-imagemin");
const webp = require("gulp-webp");

const png = () => src("src/img/**/*.png")
  .pipe(imagemin())
  .pipe(dest("dist/img"));

const jpg = () => src("src/img/**/*.{jpg,jpeg}")
  .pipe(imagemin())
  .pipe(dest("dist/img"));

const webp = () => src("src/img/**/*.{png,jpg,jpeg}")
  .pipe(webp())
  .pipe(dest("dist/img"));

const img = series(parallel(png, jpg), webp);

module.exports = { img };
```
I hope you are as amazed as I am about those new features! Happy bundling!