Skip to content
tezvyn:

How would you use dynamic import() to lazy-load a component-specific library?

Source: developer.mozilla.orgMediumHow cards are made

How would you use dynamic import() to lazy-load a component-specific library?

Tests lazy loading and bundle splitting. Good answers call import() inside the component lifecycle, await the module namespace, let the bundler split the chunk, and handle loading and error states. Bad answers put import() at top level, defeating lazy loading.

What's really being asked

This question evaluates whether you understand dynamic imports as a runtime code-splitting tool rather than just syntax trivia. The interviewer wants to see that you know import() is promise-based and lazily evaluated, that you can tie it to a component lifecycle, and that you think about the UX implications of asynchronous loading. It also checks if you trust the bundler to do its job once you use the right syntax.

The full answer

First, move the import from the top of the file into the component mount or render path so it only executes when the component is actually needed. Second, await the promise returned by import() and destructure the module namespace object to access the library's default or named exports. Third, note that modern bundlers like Webpack, Vite, and Rollup automatically detect import() and create a separate chunk, so no manual configuration is required in most cases. Fourth, handle the loading gap with a skeleton or spinner and wrap the call in a try-catch block to recover from network or evaluation failures. Fifth, mention that import() never throws synchronously, so all errors surface through the promise rejection.

The mistakes people make

A major red flag is saying you would place the dynamic import at the module top level, which causes immediate evaluation and defeats code splitting. Another is ignoring the async nature of the returned promise and trying to use the imported bindings synchronously. Candidates also stumble by assuming dynamic imports work without a module bundler or by forgetting to mention loading and error states, which creates a janky user experience when the chunk downloads over slow networks.

What usually comes next

The interviewer may ask how you would prefetch the chunk after initial page load but before user interaction, or how server-side rendering frameworks handle dynamic imports during hydration. They might also probe how you would implement this in a specific framework like Vue's defineAsyncComponent, Angular's loadChildren, or Svelte's await blocks. Another angle is asking how to share a dynamically imported dependency across multiple components without downloading it twice.

A concrete example

Imagine a dashboard with a heavy charting library only used by an analytics modal. Instead of a static import at the top of the modal component file, you call const chartModule = await import("chart-lib") inside the modal's open handler or onMounted hook. You then instantiate the chart via chartModule.default or chartModule.createChart. While the chunk loads, the modal shows a skeleton graphic. If the request returns a 404 or the script throws, the catch block renders a fallback message. The bundler emits a separate two-hundred-kilobyte chunk that the browser only fetches when the user opens the modal.

Interview question

A developer places await import('chart-lib') at the top level of a modal component file, but the library still ships in the initial bundle. What is the root cause?

  • a.Top-level import() is evaluated immediately when the module loads, so the bundler includes it in the initial dependency graphCorrect
  • b.The bundler can only split imports that use a template literal path, not a plain string package name
  • c.Modern bundlers require explicit manual configuration to split node_modules into separate chunks
  • d.Top-level await causes the module graph to resolve synchronously, preventing the bundler from deferring the download
Why?

A dynamic import placed at the top level executes during module initialization, which makes it indistinguishable from a static dependency; moving it into a component lifecycle or event handler defers execution until the code is actually needed. Option C is tempting because candidates often assume manual setup is required, but modern bundlers automatically split dynamic imports when they are triggered at runtime.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.

See open roles