How I reduced the size of my Webpack bundle by 1000%

or how to plan the perfect diet for your web app.

At first I thought that I am exaggerating with the numbers, throwing random percentages to the air. but then I went over it again and the numbers are definitely floored.

Web development had become a wonderful thing. no obtrusive markup and no manual CSS prefixing. this is the age of tools and utils.
So what’s the bad side of web development? what are the ugly edges? and what will we find swiped under the carpet?
in short:
— dependencies
— devDependencies
— fat bundles

I don’t think that I should explain what’s not so great about dependencies in general.
but I want to talk about a very specific side effect of those dependencies - The fact that many of them are nowadays INSIDE our bundles, thus they affect the bundle size.

we are not talking about DEV-OPS here, that’s a completely different problem (if you have less than 50k files in your node_modules give me a call).
we are talking about require being our new quiet shy friend that does everything we require him to do, regardless to the fact that its client-side we are dealing with here.
There is no news here though — just an opportunity to see where have we been drawn too.

What the hack… let’s talk numbers

After working on my web app I got to a place where things were shaping up towards completeness so I thought, what the hell… lets imagine that tomorrow morning its going to be deployed, and my pretty (yet uglified) code is going to be tested in the world’s largest test environment — production (e.g. out there).

I was quite surprised to see that my single file bundled code weighted not less then 250KB GZIP (!!). people tell me I type fast — but roughly 700KB of minified Javascript seems a bit overwhelming even for me.
So I looked deep into my dependencies and found out that only 20% is actually my code.

So what….

People have worked hard to spare me some key strokes and to allow me to focus on my actual logic rather than peripherals.
Isn’t that how its supposed to be?

well, downloading 250kb of data is acceptable in a way, but parsing 700KB of uncompressed minified Javascript will consume a whole lot more than you’d expect.
loading the script in an average desktop PC caused the tab to freeze completely for 3 seconds not allowing even the loader to animate properly. only loading the file — not even starting executing my actual logic.
On mobile things looked even worse — 8–12 seconds of completely frozen page, not to mention download time over mobile network.

Jumping forward in time

I took a deep breath and read hundreds and even thousands line of code that were in-fact part of my app.
My biggest thought after doing so for a while was:

Because my dad always taught me to be a “do-er” rather than a “talker”, I went over the core modules that constructed my app and started replacing them with my own simplified versions to see whether My feeling is justified or maybe they were all necessary.

Before trying to replace React I found out about the wonderful Preact by Jason Miller which replaces React for the price of 3kb gzip, no work is needed there.

After a week I couldn’t believe what I saw. I had a clone version of every core module I’ve used — React, React-dom, Redux, React-router, Redux-react, Reselect, html5 routing and more.
they all did at least 70–80% of what the original module offered and obviously 100% of what I needed.

I packed it all in a wrapper module that acted like most of the modules mentioned above in terms of exports and methods. and Little did you know, weighted a surprising 15KB gzip.
For the sake of maintenance and sharing I’ve decided to publish it for the angry ones like myself to use.

Enter: Trixion

The module I’ve create is called trixion and it’s only external module is Preact.

When creating trixion I’ve created a comparison table that shows differences between multiple boilerplate projects:

Project                          | stargazers | minified | min+gzip react-redux-universal-hot-example|    5713   | 561.3kb  | 170.3kb
react-redux-starter-kit | 3864 | 103.8kb | 38.9kb
react-slingshot | 3262 | 210.4kb | 59.3kb
react-isomorphic-starterkit | 1874 | 229.4kb | 66.8kb
28kb-react-redux-routing | 249 | 88kb | 25.9kb
trixion | - | 56.8kb | 15kb

For easing the launch I’ve created trixion-starter that allows me to start writing my code immediately without wasting time on dev-ops or so.

Ever since, I’ve started about 3 more projects and I’m very pleased — even though time had made me a bit pessimistic, I’m starting to feel that it may be possible to write modern web apps with minimal implementation!

Why are you sharing this?

For me, trixion is my new quiet friend — it does everything that I need but its lean. it allows me to write component based frontend with all the shiny latest conventions without compromising size. other popular packages are built to support endless amount of use cases, while many times your case is not complex at all, and the unneeded code resides dead in your bundle.

The bottom line here is not “use trixion” — not at all.
the message here is that you should grab your app with both hands and start examining what’s inside. be more aware of your dependencies size. know that people out there are doing amazing (lean) things and we should encourage them. If you decide to use trixion you’ll make me a happy man that’s for sure.

This is the part where I brag and try to impress you with my accomplishments. so the next time you run npm run build or webpack or so, know that there is someone out there that have no less code than you, yet his bundle doesn’t exceed ~24kb gzip.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store