[11.0 P7] Circuit can be paused by Blazor when inactivity is detected#37271
[11.0 P7] Circuit can be paused by Blazor when inactivity is detected#37271ilonatommy wants to merge 2 commits into
Conversation
guardrex
left a comment
There was a problem hiding this comment.
Hi @ilonatommy! 👋 ... Just a few NITs here.
Marking approved, but please see my suggestions for updates before merging.
I'll sit on these until the 14th. I'll also get the What's New content set up for the PRs that you've placed. I'll ping you on that later.
| ms.author: wpickett | ||
| ms.custom: mvc | ||
| ms.date: 11/11/2025 | ||
| ms.date: 06/23/2026 |
There was a problem hiding this comment.
We can go ahead and set this to the planned Pre6 release date ...
| ms.date: 06/23/2026 | |
| ms.date: 07/14/2026 |
|
|
||
| ## Automatic circuit pause on tab inactivity | ||
|
|
||
| The framework can optionally pause a circuit when the browser tab becomes hidden, freeing server memory and SignalR connections held by inactive users. Enable auto-pause using the `ConfigureBrowser` component in `App.razor`: |
There was a problem hiding this comment.
I adopted a general strategy of mentioning built-in components by name with the file name in parenthesis. It's not a super hard rule tho.
| The framework can optionally pause a circuit when the browser tab becomes hidden, freeing server memory and SignalR connections held by inactive users. Enable auto-pause using the `ConfigureBrowser` component in `App.razor`: | |
| The framework can optionally pause a circuit when the browser tab becomes hidden, freeing server memory and SignalR connections held by inactive users. Enable auto-pause using the `ConfigureBrowser` component in the `App` component (`App.razor`): |
|
|
||
| :::moniker range=">= aspnetcore-11.0" | ||
|
|
||
| ## Automatic circuit pause on tab inactivity |
There was a problem hiding this comment.
Adding my tracking comment to make sure I get the API into place at GA ...
| ## Automatic circuit pause on tab inactivity | |
| ## Automatic circuit pause on tab inactivity | |
| <!-- UPDATE 11.0 - API browser cross-links --> |
| })" /> | ||
| ``` | ||
|
|
||
| After the tab is hidden for `HiddenDelayMilliseconds` (default: 120,000 ms), the circuit pauses. If the user returns before the delay elapses, the pause doesn't happen. |
There was a problem hiding this comment.
Mmmmm ... 🤔 ... perhaps go with the more formal "occur" here? Microsoft styles favor conversational tone. Either way is fine. Ignore this if you feel strongly about using "happen."
| After the tab is hidden for `HiddenDelayMilliseconds` (default: 120,000 ms), the circuit pauses. If the user returns before the delay elapses, the pause doesn't happen. | |
| After the tab is hidden for `HiddenDelayMilliseconds` (default: 120,000 ms), the circuit pauses. If the user returns before the delay elapses, the pause doesn't occur. |
| > [!NOTE] | ||
| > Auto-pause triggers on the [Page Visibility API](https://developer.mozilla.org/docs/Web/API/Page_Visibility_API) `visibilitychange` event, whose meaning differs by platform: | ||
| > | ||
| > * On desktop, the tab becomes hidden when the user switches tabs or minimizes the window. The pause timer runs reliably and the circuit pauses gracefully after the delay. |
There was a problem hiding this comment.
| > * On desktop, the tab becomes hidden when the user switches tabs or minimizes the window. The pause timer runs reliably and the circuit pauses gracefully after the delay. | |
| > * On desktop, the tab becomes hidden when the user switches tabs or minimizes the window. The pause timer runs reliably, and the circuit pauses gracefully after the delay. |
| > * On desktop, the tab becomes hidden when the user switches tabs or minimizes the window. The pause timer runs reliably and the circuit pauses gracefully after the delay. | ||
| > * On mobile, the page also becomes hidden when the *whole app* is backgrounded (switching apps, returning to the home screen, or locking the screen), not just when switching browser tabs. | ||
| > | ||
| > On mobile, the operating system suspends the page's JavaScript shortly after the app is backgrounded (within seconds on Android, up to about 30 seconds on iOS). If `HiddenDelayMilliseconds` is longer than that window, the pause timer never fires and the circuit is dropped by the OS-initiated disconnect instead of pausing gracefully. The session is still preserved through the normal reconnection and [circuit state persistence](#circuit-state-persistence) path, but the client-side veto and deferral logic doesn't run. For this reason, graceful auto-pause isn't guaranteed and isn't a supported scenario on mobile when the app is backgrounded. |
There was a problem hiding this comment.
| > On mobile, the operating system suspends the page's JavaScript shortly after the app is backgrounded (within seconds on Android, up to about 30 seconds on iOS). If `HiddenDelayMilliseconds` is longer than that window, the pause timer never fires and the circuit is dropped by the OS-initiated disconnect instead of pausing gracefully. The session is still preserved through the normal reconnection and [circuit state persistence](#circuit-state-persistence) path, but the client-side veto and deferral logic doesn't run. For this reason, graceful auto-pause isn't guaranteed and isn't a supported scenario on mobile when the app is backgrounded. | |
| > On mobile, the operating system suspends the page's JavaScript shortly after the app is backgrounded (within seconds on Android, up to about 30 seconds on iOS). If `HiddenDelayMilliseconds` is longer than that window, the pause timer never fires, and the circuit is dropped by the OS-initiated disconnect instead of pausing gracefully. The session is still preserved through the normal reconnection and [circuit state persistence](#circuit-state-persistence) path, but the client-side veto and deferral logic doesn't run. For this reason, graceful auto-pause isn't guaranteed and isn't a supported scenario on mobile when the app is backgrounded. |
| > | ||
| > On mobile, the operating system suspends the page's JavaScript shortly after the app is backgrounded (within seconds on Android, up to about 30 seconds on iOS). If `HiddenDelayMilliseconds` is longer than that window, the pause timer never fires and the circuit is dropped by the OS-initiated disconnect instead of pausing gracefully. The session is still preserved through the normal reconnection and [circuit state persistence](#circuit-state-persistence) path, but the client-side veto and deferral logic doesn't run. For this reason, graceful auto-pause isn't guaranteed and isn't a supported scenario on mobile when the app is backgrounded. | ||
|
|
||
| The framework defers the pause while circuit-owned work is in progress (downloads, uploads, JS interop calls, Web Locks, Picture-in-Picture). It vetoes the pause entirely while focused text inputs with Blazor `@bind` bindings are edited or audio/video is playing. |
There was a problem hiding this comment.
If "inputs" means <input> elements, can that sentence clarify it? ... something like .........
| The framework defers the pause while circuit-owned work is in progress (downloads, uploads, JS interop calls, Web Locks, Picture-in-Picture). It vetoes the pause entirely while focused text inputs with Blazor `@bind` bindings are edited or audio/video is playing. | |
| The framework defers the pause while circuit-owned work is in progress (downloads, uploads, JS interop calls, Web Locks, Picture-in-Picture). It vetoes the pause entirely while focused text `<input>` elements with Blazor `@bind` bindings are edited or audio/video is playing. |
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > The `<input type="file">` element can't have its value restored after pause/resume due to browser security restrictions. Using `[PersistentState]` on a property bound to a file input causes an `InvalidStateError` that crashes the circuit. Instead, capture the file name in a separate property: |
There was a problem hiding this comment.
Also here, can this make "input" clearer? ...
| > The `<input type="file">` element can't have its value restored after pause/resume due to browser security restrictions. Using `[PersistentState]` on a property bound to a file input causes an `InvalidStateError` that crashes the circuit. Instead, capture the file name in a separate property: | |
| > The `<input type="file">` element can't have its value restored after pause/resume due to browser security restrictions. Using `[PersistentState]` on a property bound to a file `<input>` element causes an `InvalidStateError` that crashes the circuit. Instead, capture the file name in a separate property: |
The PR is moved to p7 and there are some changes, e.g. it won't be a framework feature but a package. Let's wait until we merge the PR first. |
Initial draft for dotnet/aspnetcore#67098.
Will be undrafted once the PR is reviewed and merged.
Internal previews