DEV Community

Sarah Hassan
Sarah Hassan

Posted on

Improve website performance by optimizing HTML with gulp 4 & browser-sync

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.

I'm using gulp 4 as a task runner and browser-sync. So we will need the following packages.

a- minifying:

1- install with npm:

npm install --save gulp-htmlmin
Enter fullscreen mode Exit fullscreen mode

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/'));
}
Enter fullscreen mode Exit fullscreen mode

b- compressing:

1- install with npm:

npm install --save-dev gulp-gzip connect-gzip-static

Enter fullscreen mode Exit fullscreen mode

2- create compressIndex task to compress index file

function compressIndex() {
  return src('./index.html')
    .pipe(gzip())
    .pipe(dest('dist/'));
}
Enter fullscreen mode Exit fullscreen mode

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()]
    }
})
Enter fullscreen mode Exit fullscreen mode

adding override boolean will cause this middleware to be applied to the FRONT of the stack as mentioned by Shane Osbourne here

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,
      },
    ],
  });
}
Enter fullscreen mode Exit fullscreen mode

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/'));
}
Enter fullscreen mode Exit fullscreen mode

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

Alt image show how optimization reduce file size

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

Alt image show response header

Thanks for reading!

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

Discussion (0)