Files
website-astro-stefanimhoff.de/src/content/journal/2014/gulp-tutorial-15-performance-improvements-webp-gzip.mdx
2023-06-07 12:53:56 +02:00

187 lines
5.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Introduction to Gulp.js 15: Performance Improvements with WebP and Gzip"
slug: gulp-tutorial-15-performance-improvements-webp-gzip
author: Stefan Imhoff
date: 2014-12-21T11:15:00+01:00
description: "The ultimate tutorial and guide for Gulp.js: How to improve the speed and performance of your website with WebP and Gzip."
cover: /assets/images/cover/gulp.svg
tags: ["code"]
series: gulp
---
This is the 15th part of my series, _Introduction to Gulp.js_. Today Ill add tasks for performance improvement of the website with WebP for images and Gzip for text files.
## Using WebP for images
[WebP](https://developers.google.com/speed/webp/) is a new image format developed by Google. With WebP, its possible to achieve much better compression with better quality, as with JPEG or PNG. Multiple browsers like **Google Chrome**, **Opera**, or **Konquerer** support this image format.
On my website, I use a header image which is in JPEG format **69 KB** in size, the same image is in WebP **44 KB**. WebP can reduce the size of images by **25-34%**, which is a lot.
Thats why I will create a task, which creates WebP images of my PNG and JPEG images and let the server deliver the smaller format to browsers, which supports it.
First, I install the Gulp.js module for WebP:
```bash
$ npm install --save-dev gulp-webp@2.1.1
```
I add an entry to the configuration file:
#### gulp/config.js
```javascript
webp: {
src: productionAssets + '/images/**/*.{jpg,jpeg,png}',
dest: productionAssets + '/images/',
options: {}
},
```
The task is short and straightforward:
#### gulp/tasks/production/webp.js
```javascript
var gulp = require("gulp");
var webp = require("gulp-webp");
var config = require("../../config").webp;
/**
* Convert images to WebP
*/
gulp.task("webp", function () {
return gulp.src(config.src).pipe(webp(config.options)).pipe(gulp.dest(config.dest));
});
```
This task needs to be run for production and has to be executed after the revisioning of the images is finished because the server will deliver a WebP image of the same name to the browser.
#### gulp/tasks/production/build.js
```javascript
var gulp = require("gulp");
var runSequence = require("run-sequence");
/**
* Run all tasks needed for a build in the defined order
*/
gulp.task("build:production", function (callback) {
runSequence(
"delete",
"jekyll:production",
// ...,
"revision",
"rev:collect",
"webp",
callback
);
});
```
Its necessary to tell the server to rewrite the URLs of our images. There are multiple techniques for this, but Ill use a `.htaccess` file:
#### app/htaccess
```apache
---
layout: null
slug: .htaccess
---
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
AddType image/webp .webp
```
It is possible to use a `.htaccess` file and include it in the [configuration file](https://jekyllrb.com/docs/configuration/). Otherwise, Jekyll will ignore hidden files and dont copy them to the target directory.
But I like it more to add [YAML Front Matter](https://jekyllrb.com/docs/frontmatter/) and create the file this way. Another advantage is that the file isnt invisible.
If you sync your production website to a server, it will deliver to browsers, which support WebP the WebP format when requesting a JPEG or PNG.
<Banner summary="It isnt working …">
Dont wonder: The `.htaccess` file wont work with the development server. It will need a server with support for `mod_rewrite` and `mod_headers` and support `.htaccess` files.
</Banner>
## Gzip text files
Many servers compress files by default with Gzip before sending them to the browser. But it is always good to pre-gzip the files because it will be faster, as the server doesnt need to compress the file on every request. And it will need less CPU and the compression rate will be much higher with pre-gzipped files because many servers dont use the maximum compression rate.
First, I install the Gulp.js module:
```bash
$ npm install --save-dev gulp-gzip@1.2.0
```
I add an entry to the configuration file:
#### gulp/config.js
```javascript
gzip: {
src: production + '/**/*.{html,xml,json,css,js}',
dest: production,
options: {}
},
```
Next, I create the task, which is short:
#### gulp/tasks/production/gzip.js
```javascript
var gulp = require("gulp");
var gzip = require("gulp-gzip");
var config = require("../../config").gzip;
/**
* Gzip text files
*/
gulp.task("gzip", function () {
return gulp.src(config.src).pipe(gzip(config.options)).pipe(gulp.dest(config.dest));
});
```
I add the task in my production build file to a JavaScript Array together with the `webp` task because this task and the Gzip task may run in parallel; WebP works with images and Gzip with text files.
#### gulp/tasks/production/build.js
```javascript
var gulp = require("gulp");
var runSequence = require("run-sequence");
/**
* Run all tasks needed for a build in the defined order
*/
gulp.task("build:production", function (callback) {
runSequence(
"delete",
"jekyll:production",
// ...,
"revision",
"rev:collect",
["webp", "gzip"],
callback
);
});
```
## Conclusion
This concludes the 15th part of my series _Introduction to Gulp.js_. We learned how to convert images to the WebP format and how to compress text files with Gzip. Every byte we can reduce will increase the speed of the website.
<Figure>
<MoreLink href="https://github.com/kogakure/gulp-tutorial" text="View Source on GitHub" />
</Figure>