TanStack AI version
@tanstack/ai-client 0.22.1
Framework/Library version
React 19.2.7
Describe the bug and the steps to reproduce it
When a response is streaming, switching to another browser tab makes chunk processing almost stop. When I return to the tab, it catches up.
I first saw this with useChat in React. The same problem happens with ChatClient directly, so it does not look related to React.
Steps to reproduce
- Open the StackBlitz repro.
- Click Run real hidden-tab test.
- Immediately switch to another tab.
- Wait at least 15 seconds, then return.
In the real hidden-tab test, only 16 chunks were processed during 15.9 seconds in the background. Across the full 2,004-chunk run, the largest gap between chunks was 1,001 ms.
Expected
The client should keep consuming stream chunks while the tab is hidden.
Actual
Chunk processing slows to roughly one chunk per second in the hidden tab, then catches up when the tab becomes visible.
Likely cause
In @tanstack/ai-client 0.22.1, ChatClient.consumeSubscription() waits for this after every chunk:
await new Promise((resolve) => setTimeout(resolve, 0))
On current main, commit 3301398 moved this await into processIncomingChunk(). It is still awaited once per chunk, so the behavior is unchanged.
Browsers throttle timers in hidden tabs. Since this timer is awaited inside the stream loop, it also delays requesting the next chunk.
I tested this local change and it fixed the problem:
if (typeof document === 'undefined' || !document.hidden) {
await new Promise((resolve) => setTimeout(resolve, 0))
}
typeof document is safe here because typeof does not throw when document is unavailable. Node.js, SSR, and Web Workers therefore keep the existing timer yield. Visible browser tabs also keep the existing behavior. The timer is skipped only when a browser document exists and the page is hidden.
There may be a better scheduling or batching fix for the library.
History
Git history shows that the per-chunk timer was introduced in #61 as part of the chunk processing overhaul.
I can open a PR if that would be helpful.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/chatclient-token-streaming-stalling-demo
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Yes, I think I know how to fix it and will discuss it in the comments of this issue
Terms & Code of Conduct
TanStack AI version
@tanstack/ai-client 0.22.1
Framework/Library version
React 19.2.7
Describe the bug and the steps to reproduce it
When a response is streaming, switching to another browser tab makes chunk processing almost stop. When I return to the tab, it catches up.
I first saw this with
useChatin React. The same problem happens withChatClientdirectly, so it does not look related to React.Steps to reproduce
In the real hidden-tab test, only 16 chunks were processed during 15.9 seconds in the background. Across the full 2,004-chunk run, the largest gap between chunks was 1,001 ms.
Expected
The client should keep consuming stream chunks while the tab is hidden.
Actual
Chunk processing slows to roughly one chunk per second in the hidden tab, then catches up when the tab becomes visible.
Likely cause
In
@tanstack/ai-client 0.22.1,ChatClient.consumeSubscription()waits for this after every chunk:On current
main, commit 3301398 moved this await intoprocessIncomingChunk(). It is still awaited once per chunk, so the behavior is unchanged.Browsers throttle timers in hidden tabs. Since this timer is awaited inside the stream loop, it also delays requesting the next chunk.
I tested this local change and it fixed the problem:
typeof documentis safe here becausetypeofdoes not throw whendocumentis unavailable. Node.js, SSR, and Web Workers therefore keep the existing timer yield. Visible browser tabs also keep the existing behavior. The timer is skipped only when a browser document exists and the page is hidden.There may be a better scheduling or batching fix for the library.
History
Git history shows that the per-chunk timer was introduced in #61 as part of the chunk processing overhaul.
I can open a PR if that would be helpful.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/chatclient-token-streaming-stalling-demo
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Yes, I think I know how to fix it and will discuss it in the comments of this issue
Terms & Code of Conduct