SSR responses stall under concurrent load in a Qwik app using routeLoader$
0 reputation · 23 Jul 2022, 20:26 UTC
0 reputation · 23 Jul 2022, 20:26 UTC
I'm designing the data-loading layer for a Qwik 1.x application and trying to understand one behavior before committing to an architecture: when many requests hit the server at once, streamed SSR responses appear to stall until async work in routeLoader$ or server$ functions completes, delaying the flushed HTML chunks for every waiting request.
My understanding is that Qwik streams HTML and serializes application state progressively so the client can resume without hydration. What I can't resolve from the documentation is how this interacts with concurrency: whether a slow loader blocks only its own request's stream or can degrade other in-flight requests on a saturated Node server, and whether large serialized state inflates time-to-first-byte enough to matter under load.
There is also the client side: event handlers are lazy-loaded per chunk, so a burst of users triggering uncached chunks without prefetching could spike latency against the origin. I am unsure whether to treat that as a framework concern or purely a CDN caching concern.
Is the concurrency-related stall in streamed SSR a documented, expected behavior of Qwik's streaming model, or strictly an infrastructure saturation problem? Does Qwik provide any documented mechanism to bound or isolate slow routeLoader$ work per request? And is there a documented way to verify that prefetching has actually populated chunk caches before first interaction?
31275 reputation · 24 Jul 2022, 02:56 UTC
In Qwik 1.x, a slow routeLoader$ blocks the completion of the specific request it belongs to, but it does not natively block other concurrent requests unless the server's event loop is saturated. If you are observing a global stall where all in-flight responses pause until a specific loader finishes, you are likely encountering infrastructure saturation or synchronous blocking code rather than a framework-level concurrency lock.
While Qwik streams HTML chunks progressively, several factors can create the appearance of a framework-level stall under load:
server$ or routeLoader$ function performs CPU-intensive synchronous work (e.g., heavy JSON parsing or complex loops), it blocks the Node.js event loop. This prevents the server from flushing chunks for any active request.To determine if the stall is caused by Qwik's streaming model or your infrastructure, perform the following tests:
routeLoader$ logic is asynchronous. Replace suspected heavy logic with a synthetic delay to see if the stall persists: await new Promise(res => setTimeout(res, 2000));.autocannon to simulate concurrent users. If the latency increases linearly across all requests regardless of which route is hit, the bottleneck is likely the Node.js event loop or the underlying hardware.The latency experienced when users trigger uncached JS chunks is an infrastructure and CDN concern, not a framework bug. Qwik's lazy-loading model relies on the efficiency of the delivery network. To mitigate this, ensure your build artifacts are cached at the edge with long Cache-Control headers.
There is no built-in "prefetching status" API for the browser cache. To verify that chunks are being populated before interaction, monitor the Network tab for .js requests triggered by prefetch hints or hover events before the actual click occurs.
Diagnostic Detail Needed: Are you using a custom Node.js adapter or a managed platform (e.g., Vercel, Netlify, Cloudflare)? The underlying runtime's handling of HTTP streaming varies significantly.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.