Statically compressing built assets can have a massive performance impact on your website, reducing the amount of data your users have to download. If you use Webpack to build your sites, there's a plugin for this called CompressionWebpackPlugin
, which supports compressing assets with any supported algorithm in zlib
, such as Broli and Gzip.
However, modern browsers have begun to accept Zstandard (zstd) encoded assets nowadays, which can offer higher compression rates than something like Brotli and Gzip, while also being faster to encode/decode.
Zstandard and CompressionWebpackPlugin
CompressionWebpackPlugin
offers the ability to pass a custom algorithm
, which means we can add support for Zstandard very quickly and easily. This blog post won't dive into deep webpack configuration and assumes some previous familiarity there, but if you already have another CompressionPlugin
definition, this should be very familiar.
Install @mongodb-js/zstd
with your package manager of choice, and then add something like the following to your webpack config:
const { compress } = require('@mongodb-js/zstd');
module.exports = {
// ...,
plugins: [
// ...,
new CompressionPlugin({
filename: '[path][base].zst[query]',
algorithm: function(input, options, callback) {
compress(input, options.level ?? 3).then((result) => {
return callback(null, result);
}).catch((err) => {
return callback(err);
});
},
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8,
}),
]
}
Now, once your site is built, you'll see zst
assets generated alongside your css
, js
, etc. (once it meets your configured thresholds). You can see all of the different CompressionWebpackPlugin
options in their documentation, and if you want to tweak the compression level, you can do so using compressionOptions
:
new CompressionPlugin({
filename: '[path][base].zst[query]',
algorithm: function(input, options, callback) {
compress(input, options.level ?? 3).then((result) => {
return callback(null, result);
}).catch((err) => {
return callback(err);
});
},
compressionOptions: {
level: 6,
},
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8,
})
Serving Compressed Assets
To serve these assets, you'll need a compatible web server. For my testing, I used nginx
with the zstd_static
directive from the zstd-nginx-module
nginx module.