# Journey for minimizing bundle.js

## Background

I’m working at Pluto network and making Scinapse now.

I’ve been living at S.Korea which has one of the best internet infrastructures.
But I knew that 70% of our users are from Southeast Asia or Africa. and generally, they had poor network infrastructure.

Pluto’s vision statement is Breaking down barriers in academia.

We all know a large JS size can undermine the user experience and become a barrier.
As a one man in Pluto network, I wanted to break this barrier as long as possible.

And even if the internet infrastructure is good, nobody likes the slow first screen or the slow first interaction.

There are many studies and papers about user experience concern with page speed.

Web Site Delays: How Tolerant are Users?

The impact of network service performance on customer satisfaction and loyalty: High-speed internet service case in Korea

## Tech-Background

Scinapse is using Universal Rendering.

Yeah. we all know it brings faster initial page load and SEO optimization.
However, it never speeds up the initial interaction.

What I mean is this.
as soon as you connect to the Scinapse, the users can see the search input element. (from server side rendering)
But if the user write something in input field before JavaScript is loaded, it will be erased because our javascript initialize it.
All interactions should not be allowed until JavaScript is loaded.(toggle login modal, etc…)

I remember that Angular team has made “rewind” method, but IDK how it is now.

## Define Problem

I already used Webpack’s production mode and set NODE_ENV as production.
Also applied UgilfyWebpackPlugin which decreases bundle size a lot.

As the result, the bundle size was 1.8MB without Gzip.

To further reduce, I had to know where it took up a lot of capacity.
Fortunately, Webpack team provides the nice plugin called webpack-bundle-analyzer.

As you can see, Lodash, MomentJS, Material-UI, JQuery take so many spaces.

I planed to apply Tree Shaking and remove unneeded dependencies and upgrade webpack along with loaders.

## Apply Tree shaking

The most important part is connecting Typescript with Babel.
I solved this problem with following articles.

The key is using ES2015 module system with Typescript and hand over it to Babel.

After applying this, Lodash and some other libraries became small.

RESULT

1.8mb -> 1.6mb

## Replace MomentJS to date-fns

I strongly recommend to change MomentJS to other library.
I know MomentJS has long history and strong community power.
However, it’s too heavy unless you use almost every feature of MomentJS.

There are other options.

I changed it to dafe-fns which is recommended by Dan Abramov’s tweet.

It is much lighter and has fancy API.

You can choose dayjs.
It’s super lightweight but I couldn’t have the chance to use it yet.

RESULT

1.6mb -> 1.53mb

## Apply tree shaking to material-ui

official document
It’s very easy to follow. And I think it’s not optional for who are using Material-UI.

RESULT

1.53mb -> 1.3mb

## Remove JQuery dependency

Changed the toast message library from Toastr to Notie which has zero dependency.

RESULT

1.3mb -> 1.23mb

I’ve done this in the following list order.

2. upgrade typescript version to latest.
3. remove unneeded options from webpack.config.js
4. Add new optimization rules to webpack.config.js

the most important part is 4.
this blog post was very helpful.

and you should use UgilfyWebpackPlugin for optimization.

RESULT

1.23mb -> 1.14mb

## Conclusion

BEFORE

AFTER

GZipped Result
495kb -> 291kb(52% of the original)

It was fun to define the problems, and solve the problem one by one.