Skip to content

Dynamic imports in module scripts

Astro ^4.0.0

Dynamic module loading can be leveraged for granular control over when code is imported and thus downloaded. This can be useful for optimizing performance in Astro, where scripts without attributes are automatically processed into type="module".

For more details on Astro’s script processing, refer to the official documentation.

If you want to see a more interactive example that might help explain or let you test things out better you can:

Prioritize critical modules by importing less critical modules only after the critical ones are processed.

<script>
import criticalModule from 'criticalModule';
criticalModule();
const lessCriticalModule = await import('lessCriticalModule');
lessCriticalModule();
</script>

Effects similar to client:visible, client:media, and client:idle can all be achieved with this technique.

<script>
const observer = new IntersectionObserver(async (entries, observer) => {
entries.forEach(async entry => {
if (entry.isIntersecting) {
const { module } = await import('module');
module();
observer.disconnect();
}
});
});
observer.observe(document.querySelector('#targetElement'));
</script>

Dynamically import modules based on feature flags. For example, loading a specific feature only for users who have opted in or who meet certain criteria.

<script>
if (featureFlag) {
const { featureModule } = await import('featureModule');
featureModule();
}
</script>

Import desktop-specific code that doesn’t need to be downloaded on mobile devices.

<script>
(async () => {
if (!('ontouchstart' in window || navigator.maxTouchPoints > 0)) {
const { desktopModule } = await import('desktopModule');
desktopModule();
}
})();
</script>

A button that might be rarely clicked, and when it is, the module needed to hydrate it is small enough that pre-hydration is unnecessary.

<script>
document.querySelector('#rareButton').addEventListener('click', async () => {
const { buttonModule } = await import('buttonModule');
buttonModule();
});
</script>

Considerations before using this technique

Section titled “Considerations before using this technique”

When a user clicks a button they expect it to react instantly. If you dynamically import heavy code that hydrates a button only when it is clicked that could create a delay between interaction and next paint. As a general rule any code that hydrates interactivity shouldn’t be delayed.