Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: a6e683bb5a797d976b15e5481c96473562080d55
      
https://github.com/WebKit/WebKit/commit/a6e683bb5a797d976b15e5481c96473562080d55
  Author: Chris Dumez <[email protected]>
  Date:   2026-03-12 (Thu, 12 Mar 2026)

  Changed paths:
    M LayoutTests/platform/ios/TestExpectations
    M LayoutTests/platform/mac-wk2/TestExpectations
    M LayoutTests/platform/mac/TestExpectations
    M Source/WebCore/page/Page.cpp

  Log Message:
  -----------
  REGRESSION(300617@main): [macOS iOS] 
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/json-module/repeated-imports.any.sharedworker.html
 is flaky failure
https://bugs.webkit.org/show_bug.cgi?id=300137
rdar://161922656

Reviewed by Basuke Suzuki.

The test repeated-imports.any.sharedworker.html was flaky because the
second import() call to the same URL (but without { type: "json" }) was
sometimes served a cached text/json response from the first import
instead of making a fresh network request to get the application/javascript
response.

It could happen because:
Worker module imports go through WorkerScriptLoader → ThreadableLoader →
DocumentThreadableLoader → CachedResourceLoader::requestRawResource().
Both the JSON and JavaScript imports create CachedRawResource objects
with the same resource type, so WebKit's MemoryCache type-mismatch check
(which protects the Document/Window path, where CachedScript::JSON vs
CachedScript::Script are differentiated) does not apply.

SharedWorkers proxy their network requests through a synthetic Document
created in Page::setupForRemoteWorker(). This synthetic page never
dispatches its window load event, so document->loadEventFinished() is
permanently false.

In CachedResourceLoader::determineRevalidationPolicy(), there is an
optimization at line 1545:
```
if (document() && !document()->loadEventFinished() && 
m_validatedURLs.contains(existingResource->url()))
    return Use;
```

This is designed to avoid redundantly re-fetching the same resource
during initial page load. But for the SharedWorker's synthetic page,
loadEventFinished() is always false and m_validatedURLs is never
cleared, so this optimization applies permanently. After the first
import caches the URL, the second import hits this check and returns
Use, bypassing all freshness and revalidation checks. The stale
text/json response is served for what should be a JavaScript import.

The flakiness (rather than consistent failure) is because
MemoryCache::pruneSoon() is scheduled after the first import's client is
removed. If the prune timer fires and evicts the resource before the
second import arrives, the cache misses and a fresh request succeeds. If
not, the cached response is reused and the test fails.

DedicatedWorker is unaffected because it proxies through the parent
page's Document, whose load event fires normally, so the m_validatedURLs
check is bypassed.
The Window path is unaffected because it uses CachedScript with distinct
JSON/Script types that trigger a type-mismatch reload.

To address the problem:
Call document->dispatchWindowLoadEvent() on the synthetic page in
Page::setupForRemoteWorker() before attaching it to the frame. This sets
m_loadEventFinished = true and calls documentDidFinishLoadEvent() (which
clears m_validatedURLs), preventing the optimization from
inappropriately applying to worker resource loads. The event dispatch
itself is a no-op since the synthetic page has no listeners.

* LayoutTests/platform/ios/TestExpectations:
* LayoutTests/platform/mac-wk2/TestExpectations:
* LayoutTests/platform/mac/TestExpectations:
* Source/WebCore/page/Page.cpp:
(WebCore::Page::setupForRemoteWorker):

Canonical link: https://commits.webkit.org/309170@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to