Door 15 | JS Adventskalender
Skip to content

Door 15

Published: at 07:00 AMSuggest Changes

Dynamic Imports – Loading Modules On Demand

Since the introduction of ES6 modules, JavaScript enables clear structuring of code into reusable building blocks. Often, however, you don’t want to include all modules directly when loading the page, but only when they are actually needed – for example, for performance reasons or to optimize the startup time of an application. This is where Dynamic Imports come into play.

What are Dynamic Imports?

Instead of including all modules upfront with a static import at the beginning of a file, the dynamic import via the import() function enables Lazy Loading of modules. This means a module is only loaded when the corresponding code is executed.

Syntax:

import('./path/to/module.js').then((module) => {
  // Module was loaded
  module.default(); // If the module has a default export
});

Unlike the static import statement, which is executed directly when loading the script, import() is asynchronous and returns a Promise. This way, you can selectively and delayed load modules as soon as they are needed.

Why Dynamic Imports?

  1. Performance & Load Time Optimization:
    Large applications consist of many modules. Through dynamic import, only those parts of the code that are actually needed are loaded. This significantly reduces the initial load time.

  2. Code Splitting:
    In combination with build tools like Webpack or Rollup, the code can be automatically split into smaller bundles (Code Splitting) and dynamically loaded. The result: more efficient resource usage and a faster user experience.

  3. Better User Experience:
    Features or components that are rarely used don’t need to be loaded directly at app startup. This saves bandwidth, reduces initialization times, and leads to a more responsive application.

Simple Example

Suppose we have a module mathUtils.js that performs an expensive calculation:

File: mathUtils.js

export function expensiveCalculation() {
  console.log('Performing expensive calculation...');
  return 42;
}

File: main.js

document.getElementById('loadButton').addEventListener('click', async () => {
  const module = await import('./mathUtils.js');
  const result = module.expensiveCalculation();
  console.log('Result:', result);
});

Using with Async/Await

async function loadModule() {
  try {
    const module = await import('./myModule.js');
    module.doSomething();
  } catch (error) {
    console.error('Failed to load module:', error);
  }
}

loadModule();

Practical Use Cases

1. Route-based Code Splitting in SPAs:

async function loadRoute(route) {
  switch (route) {
    case '/about':
      const aboutModule = await import('./routes/about.js');
      aboutModule.render();
      break;
    case '/contact':
      const contactModule = await import('./routes/contact.js');
      contactModule.render();
      break;
  }
}

2. Loading Heavy Libraries on Demand:

async function handleChartClick() {
  if (!window.Chart) {
    const chartModule = await import('chart.js');
    window.Chart = chartModule.default;
  }
  // Use Chart.js
}

3. Feature Detection:

async function enableAdvancedFeatures() {
  if ('IntersectionObserver' in window) {
    const module = await import('./advancedFeatures.js');
    module.init();
  }
}

With Webpack/Vite

Modern bundlers automatically create separate chunks for dynamic imports:

// Webpack will create a separate chunk for this
button.addEventListener('click', async () => {
  const { feature } = await import(/* webpackChunkName: "feature" */ './feature.js');
  feature();
});

Conclusion

Dynamic Imports are a powerful tool for optimizing the performance and user experience of JavaScript applications. They enable targeted loading of code only when it’s actually needed, resulting in faster load times and more efficient resource usage. Combined with modern build tools and frameworks, they form the foundation for modern, performant web applications.

Use Dynamic Imports in your next project and experience how they improve your application’s performance!


Previous Post
Door 16
Next Post
Door 14