Speed Up Your Website by 300%!
Learn how to speed up a website by an average of 300% by configuring a web server to GZip its responses.
Table of Contents 📖
Speeding Up Your Website
Websites can be sped up drastically by compressing the content it serves up. A common form of data compression is GZip data compression. GZip is commonly used in web development because the HTTP protocol includes the ability to gzip data.
SUCCESS: GZipping responses will have a positive effect on SEO!
Analyzing Bundle Sizes
Webpack is a common module bundler used to bundle website assets such as HTML, JavaScript, images, etc. It has a Bundle Analyzer plugin allows you to see the size of the bundles in your build. This is useful for seeing what is contributing to the overall size of a bundle. Specifically, it lists 3 different size definitions:
- stat - The input size of the files before any transformations, like minification.
- parsed - The output size of the bundle.
- gzip - The size of the bundle after gzip compression.
Running this Webpack plugin for my blog website outputs the following sizes. Take note of the large difference between parsed and gzip. A wopping 3 times difference!
- stat - 1.67 MB
- parsed - 607.64 KB
- gzip - 191.35 KB
INFO: Webpack will actually emit a warning for any bundle that is larger than 244 KB.
There are other Webpack plugins that would allow me to GZip my bundle when it is built. However, not all clients support GZip compression so I would rather rely on a web server like Nginx to handle the GZip process at runtime.
Nginx and Gzip
Nginx allows us to configure compression and decompression of responses. Compressing responses significantly reduces the size of the transmitted data. Gzip is enabled in Nginx by setting the gzip directive to on.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '[$time_local]: $status $remote_addr "$request"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
gunzip on;
gzip_types text/plain text/html application/javascript application/x-javascript text/javascript;
include /etc/nginx/conf.d/*.conf;
}
ERROR: Note that compression isn't a fix all as compression happens at runtime. This can negatively affect performance by increasing the processing overhead. Although, at least in my experience, the benefits of GZip far outweigh the negatives.
By default, Nginx compresses only responses with the MIME type of text/html. Therefore, to compress JavaScript we have to add it to the gzip_types directive. Also, not all clients accept compressed data. Therefore, to serve both clients, we can use the gunzip directive and set it to on. This directive will make Nginx decompress data on the fly when sending it to a client that doesn't accept Gzip encoding.
HTTP Headers at Play
If we check out the headers of my blog website using my Chrome Extension WittCepter, we can see the following request and response headers.
Accept-Encoding -> gzip, deflate, br, zstd
Content-Encoding -> gzip
If we resend this request with the Accept-Encoding header removed (which can easily be done with my Chrome Extension WittCepter), we can see the absence of the Content-Encoding header in the response.