Tree-shaking is an important way to reduce the size of your bundle and improve performance. See how you can do it in your React apps.
Tree-shaking is a concept in frontend development that involves the elimination of dead code or unused code. It depends on the static syntax of import and export modules in ES6 (ES2015). By taking tree-shaking concepts into consideration when writing code, we can significantly scale down the bundle size by getting rid of unused JavaScript, thereby optimizing the application and increasing its performance.
Tree-shaking has become quite popular in modern web development due to the rise of ES6 import and export statements, which help with static analysis of JavaScript files. This basically means that, at compile time, the compiler can determine imports and exports and programmatically decide which code should be executed, as opposed to Common JS and AMD modules, which are both analyzed dynamically. Examples of both ES6 imports and CommonJS imports are shown below where the size bundle of ES6 imports is drastically reduced as opposed to using CommonJS modules for importing packages.
// CommonJS example of importing a package. The entire package is imported
const lodash = require('lodash'); 70.7K (gzipped: 24.7k)
// ES2015(ES6) Sample of importing a specific dependency with tree shaking
import isArray from 'lodash/isArray' 1K (gzipped: 505)
Taking a more in-depth look at the example above, CommonJS Modules does not support tree-shaking as a result of it being analyzed dynamically. However, the advantages of tree-shaking here are clear. By utilizing the ES6 technique of importing dependencies just like the lodash package, the size of the dependency is comparatively massive. On the other hand, using the tree-shaking technique of importing a dependency by importing what’s required from the global package reduces the size of the imported dependencies.
The concept of tree-shaking is really important when it comes to building an optimized codebase because it can significantly reduce the bundle size of the application that is being developed. The dependencies we installed in our application can result in a laggy performance for our applications. The reason is because most of the packages we install really don’t need all of their dependencies and this results in importing large bundles where we end up needing just a small part of the bundle. A typical example is the lodash package like the example above, where you only need to import one of its dependencies, and then, instead of having to install the entire lodash package, we only import a fraction of it.
Having to implement tree-shaking with React will require you to have a module bundler that will bundle the entire codebase. A useful example for achieving this task is using either webpack or Rollup for bundling your application.
webpack is a JavaScript module bundler and its main purpose is to bundle JavaScript files for usage in the browser. webpack supports tree-shaking, but a bit of concern with this support is that webpack uses the babel-preset-env package, which bundles your files and transforms the files back to CommonJS module. Because CommonJS is not statically typed, that means tree-shaking the bundles will become difficult.
In order to achieve tree-shaking while bundling the application, there are some configurations that will be required to enable tree-shaking with webpack, shown below.
// webpack.config.js
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: babel-loader,
/* This configuration aids babel-preset-env to disable transpiling of import or export modules to commonJS */
options: {
presets: [
[ 'es2015', { modules: false }]
]
}
}
}
]
},
plugin: [ new HtmlWebPackPlugin ({
template: './src/index.html',
fileName: './index.html'
});
}
Another concept to consider before we can shake trees with webpack is configuring the side effects. Side effects occur when a function or expression modifies state outside its own context. Some examples of side effects include making a call to an API, manipulating the DOM, and writing to a database. In order to exclude such files or make webpack aware of the state of the files it’ll be transpiling, we can go ahead and configure this in either the package.json file or within the webpack.config.json file like so:
// package.json
{
"name": "Tree Shaking Project",
"side-effects": false,
// And for when you want to notify webpack of files with side-effects.
"side-effects": [
"name-of-file.js
]
}
The same can be configured within webpack configuration file, which can be found here in the docs.
// webpack.config.json
module.exports = {
modules: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: babel-loader,
side-effects: false
}
}
]
}
}
Therefore, in order to take advantage of tree-shaking with webpack, we need to adhere the following principles:
• Configure webpack option to ignore transpiling modules to commonJS.
• Use ES2015 module syntax (i.e. import and export).
• Configure side effects property option in package.json file of the project.
Rollup is a module bundler for JavaScript that compiles small pieces of code into something larger and more complex, such as a library or application. 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.
By default, using Rollup as a module bundler for your application already has the tree-shaking feature enabled without the need of configuring any additional files or installing an automated minifier to detect unused dependencies in the compiled output code. This is because its approach is based on only the import and export statements.
Building applications with several libraries without implementing tree-shaking will drastically affect the performance of the application. Therefore, it is an ultimate rule to always include good tree-shaking practices in order to improve web performance.
Check out our All Things React page that has a great collection of info and pointers to React information – with hot topics and up-to-date info ranging from getting started to creating a compelling UI.
Gift Egwuenu is a developer advocate and technical educator with more than five years of experience in the web development industry. She has a passion for building tools and products that help businesses grow. She enjoys sharing her knowledge and experience through speaking engagements, writing and other educational initiatives. Gift's areas of expertise include web development, JAMstack and career advancement, and she is dedicated to helping others improve their skills and succeed in the tech industry. Gift enjoys reading, cooking and traveling when she is not working.