The original address of this article is:
http://jmduke.com/posts/how-i-cut-my-webpack-bundle-size-in-half/, by @Justin Duke

When I first started Buttondown, I focused on two things:

1. It builds quickly.

2. It works fine.

Notably absent from the list is performance. Buttondown is not a slow application, but it is cumbersome: package files under development are measured in megabytes and take a long time to load first.

Now that its core features have stabilized and there are no particular pressing needs, I want to shift the focus of the project to maintenance, a big part of which is to see what I can do to reduce package files.

Well, yes, 4M, certainly uncompressed, but still too big for Buttondown applications. I decided to cut that size in half, which was the front end principle that we applied from the beginning, combining best practices and common sense.

0. Analyze the package file

I know the package file is big, but I don’t know why it’s so big. Fortunately, there is a tool called Webpack-bundle-Analyzer that can analyze your Webpack data and draw a visual tree to see the footprint ratio.

It looks like this:

1. To abandon the jQuery

“You really need jQuery” this is a common question, it has its own website, and in this case the answer is no. Especially since Vue makes it so easy to capture events and reference DOM, those are the only two things I actually use it for. Here’s what the comparison looks like:




The package file looks like this:

This clears about 250K bytes, reducing the package file to 3.5M. Not a huge number, but a good one.

2. Eliminate moment Locales

Moment is a heavy solution to dealing with time. It has strong Locales support, which is great, but for now I just use it to format certain UTC dates and times, so including all these Locales Settings seems unnecessary. Fortunately, I found a way to eliminate them completely from the Webpack.

The package file now looks like this:

This clears about 250K bytes, reducing the package file to 3.25M.

3. Lazy loading

ZXCVBN is a very important library for Dropbox to handle password authentication. Buttondown uses it to verify passwords.

However, it comes with a 600KB list of frequently used passwords, which are very heavy. I was thinking of cloning the repository and reducing the list, as others have done, but that didn’t seem ideal. So I decided to try lazy loading to delay the loading time – implementing Webpack lazy loading.

This is annoying for some of the configuration requirements of lazy loading (especially the correct publicPath value), but the resulting difference is nice and compact. The actual code changes are a little clunky, and I don’t like how strongly the actual implementation is coupled to WebPack, but the results are hard to argue with.


The package file now looks like this:

This clears about 750K bytes, bringing the package file down to 2.5M, and we’re almost done!

4. Selectively export LoDash

Finally, I’ll end with the most typical example of replacing a full LoDash import with the selected content.

This is very simple (and boring) and leads to a very boring difference, so I’ll just show one example of it. Rest assured, the rest look the same:

The package file now looks like this:

This clears about 450K bytes, bringing the package file down to 2.08M, not half that, but close.

The next step

2M is still big (even if it’s not compressed), it’s bigger than I thought it would be, but I’m pretty happy with the result. I want to learn more about Webpack, which provides the quality of the code base, and smaller package files have an important impact on bounce rates.

There are definitely some things I can do to narrow down the code space:

1. Remove extra fonts.

2. Get rid of moment completely and write a custom date management tool.

3. Lazy loading flatPickr (it’s only used in a few places)

These are all future improvements.

Further reading

1. Paul Irish’s perf audit of Reddit

2. The Critical Request

3.Why our website is faster than yours

4. Optimizing your bundle size