ES Modules Logo ESModules.com

Performance Optimization

Maximize ES Modules performance in production.

Module Preloading

Preload modules before they're needed:

<link rel="modulepreload" href="/js/heavy-module.js">
<script type="module" src="/js/app.js"></script>

✅ Benefits: Faster load times, reduced waterfall effects

Tree-Shaking

Remove unused code during bundling:

// utils.js - exports many functions
export function add(a, b) { return a + b; }
export function multiply(a, b) { return a * b; }

// main.js - only imports what's needed
import { add } from './utils.js';
// multiply() is removed from final bundle!

Requirements:

  • Use ES Modules (not CommonJS)
  • Avoid side effects in modules
  • Use named imports/exports
  • Configure bundler correctly

Lazy Loading

Load modules only when needed:

// Load heavy feature on user interaction
button.addEventListener('click', async () => {
  const { init } = await import('./heavy-feature.js');
  init();
});

HTTP/2 & Multiplexing

ES Modules work great with HTTP/2's multiplexing:

  • Load many small modules in parallel
  • No head-of-line blocking
  • Better caching granularity
  • Server push for dependencies

Bundle Splitting

Split code into vendor, app, and route chunks:

// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          utils: ['lodash']
        }
      }
    }
  }
}

Performance Checklist

✅ Do

  • Use dynamic imports for code splitting
  • Enable tree-shaking in bundler
  • Preload critical modules
  • Minimize module depth
  • Use HTTP/2 or HTTP/3

❌ Avoid

  • Deep module dependency chains
  • Large barrel files (index.js)
  • Side effects in modules
  • Circular dependencies
  • Importing everything from large libraries

Continue Learning