Modulepreload for JavaScript ES Modules
Use modulepreload to preload ES modules with dependency resolution. Learn how modulepreload differs from regular script preload and when to use it.
Detailed Explanation
Modulepreload for ES Modules
<link rel="modulepreload"> is a specialized resource hint designed specifically for JavaScript ES modules. It goes beyond regular preloading by also parsing the module and resolving its static dependencies.
modulepreload vs preload for Scripts
<!-- Regular preload: fetches only, does not parse -->
<link rel="preload" href="/js/app.js" as="script" />
<!-- Modulepreload: fetches, parses, AND resolves dependencies -->
<link rel="modulepreload" href="/js/app.mjs" />
| Feature | preload as="script" |
modulepreload |
|---|---|---|
| Fetches the resource | Yes | Yes |
| Parses the resource | No | Yes |
| Resolves static imports | No | Yes |
Works with type="module" |
Partially | Fully |
| Connection sharing | No guarantee | Guaranteed |
How Module Dependency Resolution Works
When the browser encounters modulepreload, it:
- Fetches the specified module
- Parses the module source code
- Discovers static
importstatements in the module - Fetches those imported modules as well
- Stores everything in the module map ready for instant execution
// app.mjs
import { initRouter } from './router.mjs';
import { setupStore } from './store.mjs';
import { renderApp } from './render.mjs';
<!-- Modulepreload also fetches router.mjs, store.mjs, render.mjs -->
<link rel="modulepreload" href="/js/app.mjs" />
When to Use modulepreload
- Entry point modules — your main application module that imports other modules
- Route-specific modules — modules loaded when the user navigates to a specific section
- Web workers — worker scripts that use ES module syntax
Limitations
- Does not resolve dynamic imports (
import()) — only staticimportstatements - Browser support is growing but not universal — check caniuse.com
- The
asattribute is implicitly"script"and should not be set to anything else
Example with Multiple Modules
<link rel="modulepreload" href="/js/app.mjs" />
<link rel="modulepreload" href="/js/vendor.mjs" />
<script type="module" src="/js/app.mjs"></script>
Preloading the vendor module separately ensures it starts downloading in parallel with the app module rather than waiting for the app module to be parsed first.
Use Case
A single-page application built with vanilla ES modules uses modulepreload for its entry point module. Without modulepreload, the browser discovers dependencies in a waterfall pattern (fetch app.mjs -> parse -> fetch router.mjs -> parse -> fetch store.mjs). With modulepreload, all modules are fetched in parallel, reducing JavaScript initialization time by 40%.
Try It — Preload Generator
Related Topics
Preload vs Prefetch — When to Use Each Resource Hint
Fundamentals
Using the fetchpriority Attribute for Resource Prioritization
Advanced
Preloading Critical CSS for Faster First Paint
Preload Use Cases
Resource Hints Best Practices and Common Pitfalls
Practical Scenarios
Avoiding Unused Preload Warnings
Advanced