There are two useful techniques that can be used to improve the performance of your web page:
- Minification
- Data compression
Incorporating both of these techniques reduces payload sizes and in turn improves page load times.
Measure
Lighthouse displays a failed audit if it detects any CSS or JS resources on your page that can be minified.
It also audits for any uncompressed assets.
Minification
Minification is the process of removing whitespace and any code that is not necessary to create a smaller but perfectly valid code file. Terser is a popular JavaScript compression tool and webpack v4 includes a plugin for this library by default to create minified build files.
- If you're using webpack v4 or greater, you should be good to go without doing any additional work. 👍
- If you are using an older version of webpack, install and include
TerserWebpackPlugin
into your webpack configuration settings. Follow the documentation to learn how. - If you are not using a module bundler, use
Terser
as a CLI tool or include it directly as a dependency to your application. The project documentation provides instructions.
Data compression
Compression is the process of modifying data using a compression algorithm. Gzip is the most widely used compression format for server and client interactions. Brotli is a newer compression algorithm which can provide even better compression results than Gzip.
There are two different ways to compress files sent to a browser:
- Dynamically
- Statically
Both approaches have their own advantages and disadvantages which is covered in the next section. Use whichever works best for your application.
Dynamic compression
This process involves compressing assets on-the-fly as they get requested by the browser. This can be simpler than compressing files manually or with a build process, but can cause delays if high compression levels are used.
Express is a popular web framework for Node and provides a compression middleware library. Use it to compress any asset as it gets requested. Here is an example of an entire server file that uses it correctly:
const express = require('express');
const compression = require('compression');
const app = express();
app.use(compression());
app.use(express.static('public'));
const listener = app.listen(process.env.PORT, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
This compresses your assets using gzip
. If your web server supports it,
consider using a separate module like
shrink-ray to compress via
Brotli to achieve better compression ratios.
Static compression
Static compression involves compressing and saving assets ahead of time. This can make the build process take longer, especially if high compression levels are used, but ensures that no delays happen when the browser fetches the compressed resource.
If your web server supports Brotli, use a plugin like BrotliWebpackPlugin with webpack to compress your assets as part of your build step. Otherwise, use CompressionPlugin to compress your assets with gzip. It can be included just like any other plugin in the webpack configurations file:
module.exports = {
//...
plugins: [
//...
new CompressionPlugin()
]
}
Once compressed files are part of the build folder, create a route in your server to handle all JS endpoints to serve the compressed files. Here is an example of how this can be done with Node and Express for gzipped assets.
const express = require('express'); const app = express(); app.get('*.js', (req, res, next) => { req.url = req.url + '.gz'; res.set('Content-Encoding', 'gzip'); next(); }); app.use(express.static('public'));