v156 · module map · resource timing

Retry refetch probe

Two import() calls, one failing URL, and the Resource Timing buffer as the witness. Whether the second call reaches the network — one fetch recorded, or two — is precisely what "avoid caching module failures" changed. The verdict below is read from what this browser actually did.

Import a failing URL, twice

module URL for this run:

The URL points inside this feature's folder but the file does not exist, so every real fetch of it returns HTTP 404 — which the module loader treats as a fetch failure. Press "Attempt import()" at least twice.
Attempts this run
#import() resultsettled innetwork fetches of this URL so far
no attempts yet

How the probe reads the truth

Every real network attempt for a URL — even one that ends in a 404 — lands an entry in the Resource Timing buffer, with responseStatus on it. A rejection served from the module map cache lands nothing, because no request was made. So the count of entries whose name equals the module URL is the count of network attempts:

const fetches = performance.getEntriesByType("resource")
  .filter((entry) => entry.name === moduleURL).length;

try { await import(moduleURL); }
catch (error) { /* TypeError: Failed to fetch dynamically imported module */ }

// pre-156:  second import() → count unchanged (failure cached)
// 156+:     second import() → count + 1     (real refetch)

Both attempts still reject either way — the URL really is broken. The change is only that the retry is allowed to try. The settle time column shows another tell: a cached failure rejects in well under a millisecond-scale round trip, while a refetch takes a real network round trip.

see also