[Webkit-unassigned] [Bug 270357] New: "modulepreload" load failures get stuck inside the CachedResource cache

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Mar 1 09:41:27 PST 2024


https://bugs.webkit.org/show_bug.cgi?id=270357

            Bug ID: 270357
           Summary: "modulepreload" load failures get stuck inside the
                    CachedResource cache
           Product: WebKit
           Version: Safari 17
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: WebCore JavaScript
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: justin.chines at gmail.com

Created attachment 470114

  --> https://bugs.webkit.org/attachment.cgi?id=470114&action=review

repro

ES Module preloading can be activated using the (relatively new) rel="modulepreload" link tags. If the network requests resulting from these tags fail (e.g. due to network connection being lost), then this failure will be cached, and the page will be stuck with a poisoned cache.
The result for typical SPAs is that essential modules will fail to load, and the page won't work at all. Refreshing does not fix the problem.

In the event of a network failure, the following is true:
- There is a CachedScript stored in the MemoryCache with:
    - isPreloaded() is true (m_preloadCount > 0)
    - errorOccurred() is true (m_status == LoadError, via SubresourceLoader::didFail)
- In CachedResourceLoader::requestResource, the RevalidationPolicy chosen for the resource is "Use", because of isPreloaded()
- At ScriptModuleLoader:471, after the script calls dynamic import(), it will fail immediately with "Importing a module script failed.", because of errorOccurred()

A subsequent request for the poisoned resource is _not_ seen in the Web Inspector network tab when the process is in this state, but the above exception message ends up being thrown in the script.

I don't know if this is sufficient information to understand the issue, but it's what I observed when debugging.
---
Here's how I've been able to reproduce:
1. Serve the repro.html file from a remote server
2. script.js can be anything, but a big file is easier. For example: `$ dd if=/dev/zero of=script.js bs=1024 count=1024`
3. Request repro.html in Safari 17
4. Cancel the load of script.js script by disabling the network connection
5. Re-enable network connection
6. The page is now stuck and will never load script.js, even after a standard refresh. Every refresh will print "Importing a module script failed." in the console. script.js _will not_ be in the network tab.

I realize these steps (especially #4) are a bit of a pain. Let me know if I can help out with something better.

We hit this organically from loading our web app over poor mobile connections. Support for `rel="modulepreload"` was added in Safari 17 from what I see online, so I suppose these are recent codepaths. I am happy to provide more information to help fix this issue if needed.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20240301/15c79a95/attachment.htm>


More information about the webkit-unassigned mailing list