Accept-Encoding HTTP-header and decides what to do. In most cases this header contains at least
gzip, deflate value. Translating to human language, browser says: "Hey, I have a question for you and I can understand, if you respond in
gzip format!". So at this step your server generates
.gz file to some cache instead of compressing it each time.
But there is another option. Let’s help our server: we can prepare this compressed
.gz file on build step and upload it to the server. In this case your server will see, that there are two files:
your-bundle.js.gz , so it will just use this
.gz file for the answer.
npm run build you will find production bundle in static/dist folder. Size of this bundle is 700K:
Generation of gzip using webpack could be achieved using compression-plugin. We don’t need to compress our assets in development, so let’s add this plugin to our production config:
Now after running
npm run build we will find
Not bad, but don’t forget that in most cases we have this file generated by server. Why did we start it if we had the same result before? Let’s do it better.
Generating of gzip is usually done by zlib. In most cases you get pretty good compression and spend not a lot of time calculating it. But you can spend a bit more time with zopfli to have better result! It is compression algorithm by Google, that generates more efficient, backward-compatible gzip. So, all browsers support it out of the box. Let’s try it! Furthermore, zopfli is supported by compression-webpack-plugin, so we just change
And after running
npm run build size of
gz bundle is 196K:
We’ve got 4% improvement for free! Google says that the output generated by zopfli is typically 3–8% smaller compared to zlib.
Have you noticed that that article about zopfli was published in 2013? But it is already 2017 and google engineers had at least 4 years to make the web better. And they did it!
We can use brotli as a compression algorithm. It is similar in speed with deflate but offers more dense compression. Since it is new format (not gzip) some old browsers doesn’t support it:
In terms of browser ⇄ server conversation it works the same way, as gzip: browser adds
Accept-Encoding header and server can answer with content of
Similarly to gzip compression, we just add the plugin to our production config:
npm run build we see:
Brotli is just 160K, that is 16% more efficient than zopfli!
First of all, you can do the same without webpack, I’ve used it just as example, because it is most popular way to build JS now.
As you can see we reduced size of our bundle by 77% using this advanced compression. It sounds amazing, but it is not always possible to just add brotli to your application, because:
- Brotli is HTTPS only. Find the reason in the end of this chromium issue;
- Your server should support brotli. For example, nginx should include brotli plugin;
- If you use any CDN — again, it should support brotli.
Now you know how to improve speed of your application in one simple step. Let’s do the web better 💪