Skip to content

Instantly share code, notes, and snippets.

@KELiON

KELiON/blog.md Secret

Created June 14, 2017 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KELiON/481c03ad0ffeb14ff02a42ef3bd69246 to your computer and use it in GitHub Desktop.
Save KELiON/481c03ad0ffeb14ff02a42ef3bd69246 to your computer and use it in GitHub Desktop.

Reduce your javascript bundle by 77%

Most of the articles about reducing javascript bundle size, generated by webpack, show how to reduce plain text size: removing big and duplicated dependencies, adding tree-shaking, splitting chunks, async loading of javascript, etc. But there is another, even more important step: compression of your javascript files.

In development (i.e. with webpack-dev-server) you usually serve plain javascript, but on production your server checks 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 gzip version of you javascript file and responds with it. Also it saves this .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: you-bundle.js and your-bundle.js.gz , so it will just use this .gz file for the answer.

Let's use react-redux-universal-hot-example to show, what we can do. It is javascript application with web pack and several dependencies. If you run npm run build you will find production-ready bundle, and size of this bundle is 700K:

https://gist.github.com/885ab3c1c585f5468fcd8e1376b12cdf

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:

https://gist.github.com/e8216b256cbdc416f1625f45750e9021

Now after running npm run build we will find .gz version for each javascript, css and svg file. Size of gzip bundle is 204K:

https://gist.github.com/6804d0956fbb640f4f53537a7b8db6a2

Not bad, but don't forget that in most cases we have this file, but it is generated by server. So, why did we start it if we had the same result before? A lot of developers stop at this point, but we won't.

Zopfli

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 algorithm option:

https://gist.github.com/b2697b5854921c6740b7682c0f0af64b

And after running npm run build size of gz bundle is 196K:

https://gist.github.com/719038fe98725c9fd71147c33449986c

We've got 4% improvement for free! Google says that the output generated by zopfli is typically 3–8% smaller compared to zlib.

https://media.giphy.com/media/D3OdaKTGlpTBC/giphy.gif

Brotli

[image:43FBBEBB-07CB-46BD-9A50-74654016B3ED-93647-0001646EF62CED96/google-brotli-algorithm-2016-01-20-01.jpg]

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! And now we can use brotli as a compression algorithm. It is similar in speed with deflate but offers more dense compression. Since it is not gzip, some old browsers doesn't support it:

[image:8490438C-D7A3-46F3-BB04-1FC104E4608D-93647-00015C4CE3B3B530/Screen Shot 2017-06-14 at 15.19.31.png]

In terms of browser ⇄ server conversation it works the same way, as gzip: browser adds br to Accept-Encoding and server can answer with content of .br file.

Similarly to gzip compression, we just add this plugin to our production config:

https://gist.github.com/e466cc473bf14e4d2795f90da373051d

And after npm run build we see:

https://gist.github.com/fc17ebb85a857bf0351dfeab2808bdf6

Brotli is just 160K, that is 16% more efficient than zopfli!

Few notes

First of all, you can do the same without webpack, I've used it just as example, because now it is most popular way to build JS.

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 💪

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment