I'm trying to figure out how to properly use webpack-html-plugin with the compression plugin, the documentation of latter is a bit scarce.
My webpack configuration declares :
output: {
filename: 'js/[name]-[hash].js',
The compression plugin is run at last
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip"
})
In the end the scripts are correctly produced and compressed.
js/app-caf3b4b3.js.gz 382 kB [emitted] [big]
I can declare the preloading of the gzipped file in the index.html
template
<link rel="preload" href="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>.gz" as="script">
But webpack is in charge for the insertion of this line :
<script type="text/javascript" src="/js/app-caf3b4b3.js">
inside of <body></body>
How can I ask webpack to use the compressed script ?
You don't need to link a compressed file in html. You must do this server-side. You can also gzip css and html files.
Set your server to send a file using gzip compression, you'll also need proper headers to tell the browser how to interpret that compressed file.
If you are using an Apache server you can enable gzip compression with an .htaccess file.
I use this for my Apache server:
# enable the rewrite capabilities
RewriteEngine On
# prevents the rule from being overrided by .htaccess files in subdirectories
RewriteOptions InheritDownBefore
# provide a URL-path base (not a file-path base) for any relative paths in the rule's target
RewriteBase /
# GZIP
## allows you to have certain browsers uncompress information on the fly
AddEncoding gzip .gz
## serve gzip .css files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
## serve gzip .js files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
## serve gzip .html files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.html $1\.html\.gz [QSA]
## serve correct content types, and prevent mod_deflate double gzip
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=is_gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=is_gzip:1]
RewriteRule \.html\.gz$ - [T=text/html,E=no-gzip:1,E=is_gzip:1]
Header set Content-Encoding "gzip" env=is_gzip
You can google for more information on how to optimize a website with gzip compression.
https://gtmetrix.com/enable-gzip-compression.html
https://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer#text_compression_with_gzip
You can do that via Webpack Compression Plugin from you SPA app or also from server side. I'll answer for the Vue.js spa that I tested it on for config. React and Angular webpacks will not be different except for the config file names.
Steps:
Create a vue.config.js
file if not already present
Add something along these lines
const CompressionWebpackPlugin = require("compression-webpack-plugin");
module.exports = {
configureWebpack: {
plugins: [
new CompressionWebpackPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: /\.(js|css)$/,
...
})
]
}
};
More options available in plugin docs.
My approach is a bit different but it served the purpose in the and and I can save a lot of data send to the client! I was also struggling with serving the compressed version with my React SSR app; in my case the brotli type with js.br extension > "bundle.js.br". The following snippet changed it in the end to serve it properly. I reduced my client-side uncompressed bundle in development mode from 1.7 MB to 0.27 MB. Try and figure it out for you. There is no extra plugin needed to serve the file. Of course, the compressed version must be generated first with webpack. For webpack brotli compression I use the npmjs packages compression-webpack-plugin in conjunction with zlib.
var express = require('express');
var app = express();
app.get('*.js', (req, res, next) => {
if (req.header('Accept-Encoding').includes('br')) {
req.url = req.url + '.br';
console.log(req.header('Accept-Encoding'));
res.set('Content-Encoding', 'br');
res.set('Content-Type', 'application/javascript; charset=UTF-8');
}
next();
});
app.use(express.static('public'));
Now let me explain my snippet above which I use for my SSR React app to serve the compressed file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With