#webdevelopment #javascript

Tree Shaking, an introduction

What is tree shaking and why is it important and useful?

The term tree shaking comes from the JavaScript world and is a form of what is otherwise referred to as dead code elimination: tree shaking allows to reduce the amount of JavaScript code to what is really needed. The term was introduced by Rollup.

The idea behind tree shaking is to imagine the various dependencies of code as a tree. On the one hand, this tree becomes bigger, more complex, and more branched over time, because more and more dependencies are added in the form of additional packages. On the other hand, older dependencies are gradually no longer integrated or used. The packages are still there but no longer “tied.”

When you “shake” this tree, everything that is not firmly attached to the trunk or branches falls to the ground – the packages that are no longer firmly tied and therefore no longer needed fall off.

In addition to minimizing and compressing JavaScript code, tree shaking is probably the most important tool for speeding up the load time of a web app – not least because it directly influences the quantity of code.

Why does this matter? 170 KB !== 170 KB

Let’s compare 170 KB of JavaScript code (compressed) with the same number of bytes for a JPEG image, as measured on a 3- to 4-year-old smartphone with a 3G connection.

In both cases, the browser needs the same amount of time for downloading, because it is the same amount of data.

But when you look at the time the browser needs for further processing of the data in each case, then it becomes clear how cost-intensive JavaScript code is. To display the image, the browser needs about 0.1 s. In contrast, the JavaScript code is first unpacked to about 500 KB of code. This code then needs about 3.5 s to parse/compile and execute: 35 times as much time!

JavaScript bytes !== JPEG bytes

How should I write my code?

The mechanism behind tree shaking relies on static code analysis enabled by EMS notation (import/export):

import [ foo ] from './bar.js'

By specifically importing variables and functions, we are already saying which parts of the code we need and which we don’t:

module/index.js:

export [ Foo, Bar ]

myProject.js:

import [ Foo ] from 'module' // ‘Bar’ is not used and is therefore removed from the bundle later by tree shaking

webpack marks these code locations on this basis so that they can be removed by tools like UglifyJS.

However, it is necessary that the source, in this case “bar.js,” is written in EMS format. In CommonJS notation, it is not possible for applications such as webpack or Rollup to perform a static code analysis on the basis of this format. Usually you don’t have any problems with files you yourself have created if in them, you use the EMS format.

Caution with dependencies

The import statement does not allow you to recognize whether the source is written in EMS format. This requires that you take a look at the package.json file of the dependency.

As you know, the dependency is resolved with the file that is below the “main” field, but bundlers like webpack or Rollup are looking for the “module” field to find an EMS version of the dependency.

Common dependencies in which the code is not in EMS format include:

Depending on the dependency, there may be ways to still use these in a manner that facilitates tree shaking. For more in this regard, refer to:

Caution with Babel, too

Once we have ensured that the conditions for tree shaking are met by how we write our imports and dependencies, only Babel can get in the way. If you use “babel-preset-env,” it will convert the EMS format into CommonJS in the default settings. To prevent this from happening, set the “modules” option to false.

Summary

  • Use webpack
  • Use the ES2015 module syntax (import and export)
  • Make sure that tools like Babel or preset-env do not convert your EMS code to CommonJS
  • Use tools like Uglify or Terser via the Production Build of webpack to also execute tree shaking

Sources