Webpack: Get it together!
You are using webpack with your react/vue/angular app, great choice, but have you looked at your bundled app size, I was working on a simple single page React + Redux + Express app.
Even that, bundled to ~2.5 MB, all the dependencies that you are importing, they don’t come for free, right. We can’t serve this to the client, it could take seconds to download for a slow connection. So what should we do? Get it together!
How? Minification? Yeah, that could be a start, let’s do that and see the size again.
Fortunately webpack comes with all these plugins so all you need to do is “plug” them. 😛
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
// Use uglify plugin for minification
new webpack.optimize.UglifyJsPlugin()
]
};
Well, it reduced the app size to a little less than 1MB, that’s not bad for start, but 1 MB is still a pretty large chunk to send over in a single network call, so what’s next? Get it together!
How? Compression, serving gzipped file in production can dramatically reduce the size.
How? Webpack has plugin for that too, compression-webpack-plugin
// Import plugin
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
// Use uglify plugin for minification
new webpack.optimize.UglifyJsPlugin(),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
]
};
It reduced the app size to 250 KB, 2 MB to 250 KB, great job, right? But we haven’t yet told the browser that we are serving gzipped file. Let’s do that. In your express add this,
app.get('*.gz', function (req, res, next) {
res.set('Content-Encoding', 'gzip');
next();
});
Still, browser isn’t able to recognise(parse) the file, especially CSS, what are we missing, see something here?
Content-Type, that doesn’t look right, let’s tell our dumb browser, types of file we are sending,
app.get('*.js.gz', function (req, res, next) {
res.set('Content-Encoding', 'gzip');
res.set('Content-Type', 'application/javascript');
next();
});
app.get('*.css.gz', function (req, res, next) {
res.set('Content-Encoding', 'gzip');
res.set('Content-Type', 'text/css');
next();
});
Note: gzipping file reduces the file size, so download time reduces but parsing time(browser takes time to understand it in the known format) increases, you can see that under that network tab. Hopefully overall time (downloading + parsing) after gzipping would be a lot lesser. It’s all about optimisation and seeing what works for you.
Thanks for reading. ❤️