Tree Shaking in JavaScript

Jan 01, 2020#javascript#terms

Tree shaking is a form of dead code elimination in JavaScript, relies on es6 import/export statements, often implemented in module bundlers like Webpack or Rollup, very important for preparing production code to achieve significant space savings.

Why we called tree shaking? — you can imagine your application as a tree. The source code and libraries you actually use represent the green, living leaves of the tree. Dead code represents the brown, dead leaves of the tree that are consumed by autumn. In order to get rid of the dead leaves, you have to shake the tree, causing them to fall.

Why we needed tree shaking? — web apps are using more JavaScript than ever, the process of of handling JavaScript (compressing, downloading, decompressing, parsing, compiling, and executing) is getting expensive. We need a technique to address the problem of JavaScript heavy applications, and that’s why tree shaking comes to rescue.

Tree shaking term was popularized by Rollup — the concept of dead code elimination has existed for some time, then supported very early in Rollup module bundler and loved by community, Webpack has caught up since version 2.

Why tree shaking only works with es6 modules — The dynamic nature of the CommonJS modules meant that tree shaking couldn’t be applied because it would be impossible to determine which modules will be needed before the code is actually run. The static syntax of ES6 modules, as any code that is used from an import can be determined without the code needing to be first run, makes possible for tree shaking.

Rollup has built-in support for tree shaking — in addition to enabling the use of es6 modules, Rollup also statically analyzes the code you are importing, and will exclude anything that isn’t actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project.

Webpack supported tree shaking since version 2 — the webpack 2 release came with built-in support for es6 modules as well as unused module export detection. Webpack 4 release expands on this capability with a way to provide hints to the compiler via the “sideEffects” package.json property to denote which files in your project are “pure” and therefore safe to prune if unused.

What should I do to take advantage of tree shaking — use es6 module syntax import/export, ensure no compilers transform your es6 module syntax into CommonJS modules, add a “sideEffects” property to your project’s package.json file, use the production mode configuration option to enable various optimizations including minification and tree shaking.

Keeping Babel from transpiling ES6 modules to CommonJS modules — we often use Babel to transpile our nice ES6 modules into more widely compatible CommonJS modules, this is great and all until we want to start tree shaking, webpack won’t know what to prune from the bundle if you decide to use them.

Keeping side effects in mind — one aspect to consider when shaking dependencies from your app is whether your project’s modules have side effects, when a function modifies something outside of its own scope, you can tell webpack a package or files are free from side effects.

With tree shaking enabled, we expect what is imported and actually used will make it to the final bundle. However, tree shaking doesn’t eliminate all unused code and doesn’t solve the problem of unused code entirely.

Don’t be disappointed if tree shaking doesn’t result in massive performance gains for your app. Tree shaking is just one way to reduce your JavaScript payload. Combine this method with others like code splitting and minification to make sure your web apps are running as efficiently as possible.