qwikloader: WebKit may defer the async module loader while a stream is held, losing pre-resume clicks
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- playwright, typescript
- Domain
- frontend, testing-qa, web-dev
Research direction
Start with the default Module emission and the error-handling.e2e.ts midstream queue-and-replay test; reproduce on Playwright WebKit while the gated Suspense child holds the stream, and compare Chromium. Done when WebKit evaluates the loader during the hold and clicks are queued and replayed, with the nonce-aware loading path verified.
Written by the indexing model from the issue text.
Description
What is it?
- Bug
Description
With the default loader emission (QwikLoaderInclude.Module: <link rel="modulepreload"> + <script async type="module" src=".../qwikloader.js">), WebKit sometimes never evaluates the loader while the HTML stream is held open (e.g. an in-order region awaiting a deferred child). Until evaluation, no qwikloader listeners exist, so user clicks during the hold are lost instead of queued and replayed at resume. Chromium evaluates the async module as soon as it is fetched and queues the clicks correctly.
Observed on the error-handling e2e app's midstream route (in-order streaming, stream held by a gated Suspense child): window._qwikEv.roots (set only by loader evaluation) never appears on WebKit within 90s, both on CI (macos-latest) and locally (macOS 26.5 / Playwright WebKit 26.5), while the same page's inline scripts (qErr swap) run fine. The behavior is bimodal — some runs evaluate promptly — so it looks like WebKit only drains ready async scripts on parser activity, and a fully quiet hold starves them. Streaming extra padding bytes mid-hold did not reliably help.
Production impact: any Qwik page whose stream stalls (slow loader, held Suspense region) has a WebKit window where clicks are dropped instead of queued.
Possible direction: emit the Module include as a tiny inline classic script that dynamic-imports the loader (<script>import("…/qwikloader.js")</script>, nonce-aware). Dynamic import evaluation rides the microtask queue, not the parser's async-script runner, so it is immune to the starvation. Needs verification on WebKit.
The error-handling.e2e.ts mid-stream queue-and-replay test parks WebKit on this issue (the invariant stays pinned on Chromium, Linux + Windows).
- Dominant language
- TypeScript
- Stars
- 22.1k
- Forks
- 1.4k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 98
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from QwikDev/qwik
-
docs router V2
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
DX enhancement V2
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
QwikDev/qwik#8480 · 2 comments ·
Maintainers usually reply within 1 day
-
[🐞] SSG (rc.0+) ignores ssr.noExternal: bundled deps are left external in the new "ssg" environmentOpen
Difficulty 4/5 3-5 days Newbie friendliness 52/100
QwikDev/qwik#9183 · 1 comment ·
Maintainers usually reply within 1 day
-
[🐞] <Pending> child reading a signal from its owner breaks when the owner re-renders (consumerBackRef[_EFFECT_BACK_REF].set is not a function)Possibly taken @intellix claimed this 2 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 35/100
Maintainers usually reply within 1 day
-
[🐞] Async useComputed$ resolved in an out-of-order <Pending> re-runs on the client at the first unrelated re-renderPossibly taken @intellix claimed this 2 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 25/100
Maintainers usually reply within 1 day
Similar issues
-
Tenant
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
MTES-MCT/Dossier-Facile-Frontend#2061 ·
Maintainers usually reply within 1 day
-
area:frontend
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
interledger/publisher-tools#905 ·
Maintainers usually reply within 1 day
-
Add: Cbeebies PL SDOpenapproved check:passed streams:add
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
iptv-org/iptv#54525 · 1 comment ·
Maintainers usually reply within 1 day
-
DB-plane provider_chat_options.* is accepted by config set but never merged into the loaded configOpen
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
area:web
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
praetorianer777/GoTome#178 ·
Maintainers usually reply within 1 day