Naturally, I am using Laravel for this project, so the packing is done using Laravel Mix on version 4.0.14 at the time of writing.
Inspecting the bundle#
The first thing I wanted to know is where does all this code come from? A big chunk probably comes from the Vue framework, but this can't account for an uncompressed bundle of 985kb. To find out what is filling your bundle webpack has a great tool called Webpack Bundle Analyzer which will create a nice view that shows you what code files are taking up the most space. Laravel mix also has a nice implementation of this plugin so I could add this without too much hassle.
The report I got back revealed that I had way too many libraries in the project, even though the project was only a few weeks old at that time.
Fixing library imports#
The first thing that stood out to me was that the bundle included the full lodash library while I only used one function. So that was the first thing I changed. Lodash actually has support for importing only single functions from its core library, and that is what I did.
// Old import import _ from 'lodash'; // New import import _get from 'lodash/get';
This trick reduced the size of lodash in the bundle from 220kb to just 37kb. However, I was not satisfied. As stated before, I only used one function and only used it one time. So, is it really worth it importing a 37kb library for a single function? Of course not! So, I actually removed lodash all together and wrote the implementation for this case myself in only five lines of code.
This reduced the bundle size to about 710kb, and I was very happy!
Removing more libraries#
Knowing that it was so easy to replace an entire library, I investigated the bundle report for any other library that could be removed. Now, this part might not be possible for all projects, but my project will only be used by me and a hand full of other users that use up-to-date browsers. Knowing this, I thought it had to be possible to remove the axios library and replace it with the fetch api.
Re-writing part of libraries#
At this point, the only big "library" that was left in my bundle was Font Awesome. I could not remove this library because those icons are just so great to use. However, the core library for using Font Awesome (excluding the icons) is 72kb in size. Which sounds like its a bit too much for just rendering SVG icons.
So, I started looking at how exactly the Vue component was built up and tried to make my own implementation that only did the basic things necessary to build up the SVG. However, this was easier said than done. Eventually, I got to a version where the SVG got loaded from the library and displayed on the screen. But the size was wrong and its position would change depending on the properties of the parent container. Also, the component I made had become overly complex and violated all rules of reactive programming.
I was glad I had tried this approach but was even more happy to go back to the component provided by FontAwesome. Optimizing is great, but it shouldn't come at a development cost.