tooling.report

feature

Dead imported code

Can dead code be eliminated from dynamic imports?

Person in shorts with blue hair walking left

Introduction

Performing Dead Code Elimination on JavaScript bundles when building for production is an important performance optimization that avoids sending unused code to the browser. Exports of a module that are not imported or used by any other module in an application can also be considered dead code and subject to removal. However, this leads to some tricky optimization cases where a module's exports are used in a way that is difficult to statically analyze. Dynamic imports are one of these cases, because the Module record returned by a dynamic import has properties for each export that can be referenced in many different ways, some of which can't be determined at build time.

The Test

This test bundles two modules - an entry module, and a utils.js module it dynamically imports to create a split point. The dynamically imported module has two exports, but only the logCaps export is used.

index.js

(async function() {
  const { logCaps } = await import('./utils.js');
  logCaps('This is index');
})();

utils.js

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

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

Once built for production, the thisIsNeverCalled function from utils.js should not be present in the resulting bundle(s).

Conclusion

browserify

tinyify is a Browserify plugin that runs various optimizations which includes dead code elimination. However, Browserify does not support lazy-loading, so it cannot complete this test.

Issues

  • N/A
parcel

The most common patterns using import() are statically analyzed for the used exports (https://parceljs.org/features/code-splitting/#tree-shaking).

Issues

webpack

Webpack doesn't understand the special destructuring syntax to elimitate dead code:

const { logCaps } = await import('./utils.js');

But it allows to manually list the exports that are used via magic comment:

const { logCaps } = await import(/* webpackExports: "logCaps" */ './utils.js');

Issues