tooling.report

feature

Dead code elimination

Can unused code paths be removed from bundles?

Person in shorts with blue hair walking left

Introduction

Bundling modules for production is generally considered to be good for performance, since it allows optimizing the size of JavaScript files based on network and browser constraints rather than an application's structure. However, modules often contain more functionality than is required by an application its current state. These unused code paths aren't necessarily a concern at an individual module level, but when modules are bundle together the amount of unused code often becomes substantial.

Dead Code Elimination is the process of removing code that is not used by the current application. Code is parsed to create an Abstract Syntax Tree which is then traversed to find unused functions and variables, and finally the tree is converted back to JavaScript source code. There are a number of tools available that can perform Dead Code Elimination on JavaScript source, with the most popular being Terser and Closure Compiler.

The Test

In this test, each build tool is configured to optimize bundles via its built-in "production" option, or using the most common configuration in cases where there is no such option. Some tools are able to perform Dead Code Elimination as part of bundling, others may rely on other tools like Terser.

index.js

import { logCaps } from './utils.js';
logCaps(exclaim('This is index'));

function thisIsNeverCalled() {
  console.log(`No, really, it isn't`);
}

utils.js

export function logCaps(msg) {
  console.log(msg.toUpperCase());
}

export function thisIsNeverCalledEither(msg) {
  return msg + '!';
}

Once built for production, both the thisIsNeverCalled and thisIsNeverCalledEither functions should be completely removed from the bundle(s).

Conclusion

browserify

(This test uses Browserify) tinyify is a browserify plugin that runs various optimizations which includes dead code elimination.

parcel
rollup
webpack

Webpack's Dead Code Elimination is implemented by annotating and removing unused module exports, then relying on [Terser] to perform Dead Code Elimination. As with minification, the preservation of some module boundaries in Webpack bundles can limit the amount of optimization Terser can perform.