RoastMyOpsec

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.

OptionWhen it winsWatch-outTakeaway
rel=preloadOne critical font, hero image, or blocking CSSWrong as= or unused preload warningsSingle asset, this navigation
rel=modulepreloadThe page’s ES module entry and its static graphUsing it on classic scripts or imagesModules only
dns-prefetch / preconnectYou will definitely talk to that origin soonPreconnecting ad and tracker originsConnection setup, not a download
No hintsA simple document with few assetsNot a security failureHealthy 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 now

FAQ

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.

Sources

Related guides