Overview
Webpack is capable of tree shaking unused code in order to make an application's bundles sizes smaller and more optimized. However, it can only do so under the correct circumstances.
I am performing a series of experiments iterating on a simple JavaScript application. I will modify its configuration and code to determine which settings result in the minimal bundle sizes.
Setup
The source code used for all of the experiments can be found here.
Here is a list of the main software used:
- NodeJS 18.17.1 & NPM 9.6.7 (included with Ubuntu Lunar Lobster)
- NPM workspaces to separate out each experiment
- BundleAnalyzerPlugin to visualize artifact results
- HtmlWebpackPlugin to generate the index.html file used to import the bundled JavaScript application.
Initial Application
This application was created by using the Webpack getting started guide but adjusting it slightly as it is placed in the ./packages/initial-app/ directory as an NPM workspace.
There are three main modifications made to the getting started app to test various parts of code splitting and tree shaking:
- Using multiple functions from the lodash library (join, sortBy, cloneDeep)
- Importing a json file. This is common when using i18n and for statically accessed configuration data.
- Importing another js file within the app. The goal here is to attempt to have this be a portion of the application that can be chunked out and ideally lazy loaded.
Results
-rw-rw-r-- 1 brian brian 107K Sep 5 19:37 app.js-rw-rw-r-- 1 brian brian 336 Sep 5 16:34 app.js.LICENSE.txt-rw-rw-r-- 1 brian brian 236 Sep 5 16:34 index.html
We really are only concerned with app.js and will ignore the others going forward.
The following diagram is the output from the BundleAnalyzerPlugin:
The lodash parsed size in the bundle is 68.48 KB.
Looking a the bundle analyzer output, we can see we receive a single js file with lodash.js, users.json, timer.js, and index.js all nested inside. This gives us our baseline that we can now make improvements on.
Experiment 1 - Treeshake lodash
The objective of this experiment is to make some minor modifications to the app configuration that result in the same user visible screen, but much better file sizes. This is done by changing how lodash methods are imported.
Results
Conclusion
This optimization trimmed about 42 KB out of the resulting app by allowing Webpack to find unused code in lodash and remove it. This is a 40% reduction in size!
Experiment 2 - Treeshake using lodash-es
The lodash-es package is a special build of lodash that packages it in the more recent ES module packaging. Let's see what effect, if any using this might have.