WHAT WE THINK?

Let’s shake some trees – how to enhance the performance of your application

Sent on: 13.11.2018 | Comments:0
Let’s shake some trees – how to enhance the performance of your application

Nowadays JavaScript applications are getting bigger and bigger. One of the most crucial things while developing is to optimise the page load time by reducing the size of the JavaScript bundle file.

JavaScript is an expensive resource when processing and should be compressed when it is about to be sent over the network.

One of the most popular techniques to improve the performance of our applications is  code splitting. It is based on splitting the application into chunks and serving only those parts of JavaScript code that are needed at the specified time. However, this article is going to be about another good practice called tree shaking.

Tree shaking  is used within the ES2015 import and export syntax and supports the dead-code elimination. Since Webpack 4 released it is possible to provide the hint for a compiler by the “sideEffects” property to point the modules that can be safely pruned from the application tree if unused. Function may be supposed to have  side effects if it modifies something outside its own scope.

Real life example

In order to introduce tree shaking concept more precisely, let’s start with creating a new project including the application entry point (index.js) and the output bundle file (main.js).

In the next step, a new JavaScript file (utils.js) is added to the src directory…

export function foo() {
console.log('First testing function')
}
export function bar() {
console.log('Second testing function')
}

…and imported in the index.js.


import { foo } from './utils.js'

foo()

Webpack 4 introduces the production and development mode. In order to get a not minified output bundle, we are supposed to run a build process in the development mode what can be defined in the package.json file.


"scripts": {

"dev": "webpack --mode development",

"build": "webpack --mode production"

}

Now, just get the terminal and run: npm run build script.

Despite, only the foo function has been required in the entry point, our output bundle still consists of both foo and bar methods. Bar function is known as a “dead code” since it is unused export that should be dropped.

console.log('First testing function');\n\nfunction bar() {\n console.log('Second testing function')

To fix this problem we are about to set the “sideEffects” property in package.json file.

{
  "name": "tree-shaking",
  "version": "1.0.0",
  "sideEffects": "false",
}

That property just tells the compiler that there are not any side effects files and every unused code can be pruned. It accepts also absolute and relative paths to the files that should not be dropped due having some side effects.

{
  "name": "tree-shaking",
  "version": "1.0.0",
  "sideEffects": "./src/file-wth-side-effects.js",
}

Minification

After we pruned unused ES6 imports and exports, we still need to remove “dead code” from the application bundle. The only thing we have to do is to set the mode configuration to production and execute npm run build.

([function(e,t,n){"use strict";n.r(t),console.log("First testing function")}]);

As we can see, the second testing function is no more included in the bundle minified file.

Use three shaking with the ES6

It is crucial to keep in mind that tree shaking pattern can be used only within the ES6 import and export modules. We cannot “shake the tree” while using the CommonJS without the help of special plugins. To solve this issue, setting the  babel-preset-env to leave the ES6 modules on their own should be performed.

{
  "presets": [
    ["env", {
      "modules": false
    }]
  ]
}

 

Exception

Removing unused modules does not work while dealing with lodash. Lodash is one of the most popular utility library. If you import a module in the way it is depicted below, it will still pull all the lodash library.

import { join } from 'lodash'

To go around that, we need to install lodash-es package and require the modules in the following way:

import join from 'lodash-es/join'

Conclusion

Let’s prove the statement from the beginning of this article! Let’s take a closer look at the sizes of the bundle file (main.js) before and after the tree shaking and minification process.

 

 

 

 

As we can see we minimized the output size significantly. When you start using tree shaking in your projects it may seem not taking a big advantage of application performance at all. You will notice how it really boosts up your work while having a more complex application tree.

Add comment: