Import on Interaction: Load When User Interacts
Learn the interview-ready mental model, practical trade-offs, and production patterns for this web fundamentals topic.
Topic content
Import on Interaction is a performance pattern that uses dynamic import() to load non-critical code only when the user explicitly interacts with a UI element. It reduces initial JavaScript bundle size while deferring cost to the moment of actual need. Combine with prefetching on hover/focus and Promise caching for smooth UX.
Static imports = pre-cooking everything before the restaurant opens. Import on Interaction = cooking expensive dishes only after the customer orders them. You save kitchen resources upfront, but the first order might take slightly longer unless you start prep on early signals like seeing the menu (hover/focus).
1Basic Click Pattern
Load the module only when the user clicks. Cache the result so subsequent clicks are instant.
const handleOpen = async () => {
if (!Modal) {
const mod = await import('./SettingsModal');
setModal(() => mod.default);
}
setOpen(true);
};2Prefetch on Hover / Focus
Start loading on early intent signals (mouseenter, focus) to hide network latency before the actual click.
<button
onMouseEnter={prefetch}
onFocus={prefetch}
onClick={handleClick}
>
Open Chat
</button>3Promise Caching
Cache the import Promise to avoid duplicate requests and simplify loading state management.
let modalPromise;
function loadModal() {
if (!modalPromise) modalPromise = import('./Modal');
return modalPromise;
}4React Hook Pattern
Encapsulate loading, caching, states, and prefetching into a reusable hook for clean component code.
- ✓Import on interaction defers heavy optional code until explicit user intent
- ✓Combine click loading with hover/focus prefetching for smoother UX
- ✓Always cache the import Promise to avoid redundant work
- ✓Provide clear loading and error states
- ✓Best for modals, editors, charts, admin tools — not core navigation
- ✓Measure both initial bundle reduction and interaction-to-ready latency