News
preload vs modulepreload for Public Pages
March 29, 2025
preload vs modulepreload for public pages is a resource-hint decision: rel=preload fetches a specific asset early with an as= type, while rel=modulepreload is for ES modules and can fetch the module graph. Use preload for the LCP image or a critical font you will use immediately; use modulepreload for the first JS module the page will import. RoastMyOpsec does not score these hints as standalone Fs; over-preloading third-party URLs is a performance and tracker problem, not a headers F.
The practical difference
MDN documents preload as a declarative fetch for something you will use on this navigation, with as="style"|"script"|"font"|"image" and matching CORS for fonts. modulepreload is specifically for classic ES module documents; browsers can discover static imports. Mixing them — preload as=script on a module, or modulepreload on a PNG — wastes connections.
Hints are not CSP. A preload to a third-party analytics host still starts a connection and may send cookies depending on attributes. Speculative loading of origins you do not need is how marketing pages pay for ads before the headline paints.
Early Hints (103) can carry the same Link relations. That is a CDN feature. It does not change the security model. CSP still has to allow what you preload.
How to choose based on what you shipped
Preload one LCP image or one critical font with correct crossorigin. Modulepreload the entry ES module on app-like public pages. Do not preload every vendor chunk “just in case.” Do not modulepreload a URL you would not allow in script-src.
| Option | When it wins | Watch-out | Takeaway |
|---|---|---|---|
| rel=preload | One critical font, hero image, or blocking CSS | Wrong as= or unused preload warnings | Single asset, this navigation |
| rel=modulepreload | The page’s ES module entry and its static graph | Using it on classic scripts or images | Modules only |
| dns-prefetch / preconnect | You will definitely talk to that origin soon | Preconnecting ad and tracker origins | Connection setup, not a download |
| No hints | A simple document with few assets | Not a security failure | Healthy default |
When preload still wins
preload still wins for a hero image or a font that is otherwise discovered late. modulepreload still wins for module-first pages. Neither wins as a way to sneak around CSP. Missing both is normal on a light marketing page.
Common mistakes
The first mistake is preloading a third-party tracker origin and calling it performance work.
The second mistake is using modulepreload on non-module assets.
The third mistake is treating missing preload as a security finding.
What a URL roast can prove
RoastMyOpsec’s free roast grades CSP and other security headers, TLS, cookies, path probes, and js-secrets. It does not score preload, modulepreload, fetchpriority, Open Graph, or JSON-LD as standalone Fs. If a preload URL is a tracker-shaped host in HTML, tracker findings may still surface — as trackers, not as a missing-hint F.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Is modulepreload a security feature?
- No. It is a loading hint for ES modules. CSP still governs what may execute.
- Should I preload all fonts?
- No. Preload the one critical face you will use immediately, with correct crossorigin.
- Does RoastMyOpsec fail missing preload?
- No. Resource hints are not standalone Fs on the free roast.