Improve website performance by optimizing HTML with gulp 4 & browser-sync
Tags: html, gulp, beginners, performance
Published: 2020-11-26 00:51:43

Today I will explain how to optimize HTML files reduce their sizes as possible.
We can achieve that by doing 3 things first `minifying` then `compressing` finally `cache them`.

First, let me explain the difference between `minify` and `compress`.

- `Minify`: remove white spaces, comments, and unnecessary characters.
- while `compressing`: the process of reducing the size of data (encoding information) using algorithms to compress ex gzip, deflate.

### What happens between server and browser?
- browser request index.html file.
- server sends a `.zip` file to the browser `(index.html.zip)` instead of the regular `index.html` version.
- The browser then downloads the `zipped file`, extracts it, and then shows it to the user.

**but how server know it’s OK to send the zipped one and not the regular index file???**

They have an agreement with 2 parts:

1 -The browser sends a header telling the server it accepts compressed content (gzip and deflate are two compression schemes): Accept-Encoding: gzip, deflate

2- The server sends a response if the content is actually compressed: Content-Encoding: gzip

*For more info read this [great article](https://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/).*

I'm using gulp 4 as a task runner and browser-sync. So we will need the following packages.
- [gulp-htmlmin](https://www.npmjs.com/package/gulp-htmlmin) to minify html files.
- [gulp-gzip](https://www.npmjs.com/package/gulp-gzip) to compress html files.
- [connect-gzip-static](https://www.npmjs.com/package/connect-gzip-static) to enable us serve zipped HTML in local server for testing during dev.

### a- `minifying`:

1- install with npm:
```
npm install --save gulp-htmlmin
```

2- create `minifyIndex` task to minify `index` set options like remove comments and whitespace.
```
function minifyIndex() {
  return src('./index.html')
    .pipe(htmlmin({ collapseWhitespace: true, removeComments: true }))
    .pipe(dest('dist/'));
}
```

### b- `compressing`:

1- install with npm:
```
npm install --save-dev gulp-gzip connect-gzip-static

```

2- create `compressIndex` task to compress `index` file
```
function compressIndex() {
  return src('./index.html')
    .pipe(gzip())
    .pipe(dest('dist/'));
}
```

3- serve compressed files for the local server 
I tried to use the following method but it failed as middleware is too late in the stack when added via the options for .html files so the server didn't serve our zipped file

```
const compression= require('compression');

browserSync({
    server: {
        baseDir: './',
        middleware: [compression()]
    }
})
```

adding override boolean will cause this middleware to be applied to the FRONT of the stack as mentioned by Shane Osbourne [here]
(https://github.com/BrowserSync/recipes/issues/4#issuecomment-252511287)

```
function serveTask() {
  // init browserSync
  browserSync.init({
    // setup server
    server: {
      baseDir: './dist/',
    },
    middleware: [
      {
        route: '', // empty 'route' will apply this to all paths
        handle: gzipStatic('./dist/'), // the callable
        override: true,
      },
    ],
  });
}
```
Note: you need also to add the regular index version as a fallback in case the server doesn’t send the content-encoding response header, which means the file is not compressed (the default on many servers).

```
function initIndexHtml() {
  return src('./index.html')
    .pipe(htmlmin({ collapseWhitespace: true, removeComments: true }))
    .pipe(dest('dist/'));
}
```

after doing html optimization in my project I succeeded in reducing index file size from `21kb` to `3.5kb`

### Test if the compressed content is served:

1- open your site and developer tools.

2- open network tab check use large request rows to be able view size before and after optimization.

3- reload.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cy7zj5u1nmwunupmdcff.png)


![Alt image show how optimization reduce file size](https://dev-to-uploads.s3.amazonaws.com/i/omwhi5s6yfo91pfb1ew2.png)

4- click as shown to display headers and response header `'Content-encoding: gzip'`.


![Alt image show response header](https://dev-to-uploads.s3.amazonaws.com/i/5n9yc6c8lb5aho4kzj2n.png)


Thanks for reading!

Hope this article helps, feel free to share it with your friends, any feedback will be appreciated :)