Tuesday, September 5, 2023

Webpack Tree Shaking Experiments


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.


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:

  1. Using multiple functions from the lodash library (join, sortBy, cloneDeep)
  2. Importing a json file. This is common when using i18n and for statically accessed configuration data.
  3. 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.


 After running `npm run build`, we get the following files in the dist dir:
-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.