Skip to content

Apply backpressure to WebViewRenderer's unacknowledged render batch queue - #68739

Open
Kebechet wants to merge 1 commit into
dotnet:mainfrom
Kebechet:webview-renderer-backpressure
Open

Apply backpressure to WebViewRenderer's unacknowledged render batch queue#68739
Kebechet wants to merge 1 commit into
dotnet:mainfrom
Kebechet:webview-renderer-backpressure

Conversation

@Kebechet

Copy link
Copy Markdown
  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making.

Stop rendering while the WebView has too many unacknowledged render batches.

Description

WebViewRenderer currently produces, serializes and dispatches render batches without bound even when the JS side has stopped acknowledging them — e.g. on Android, where the OS demotes and freezes the out-of-process WebView renderer while the backgrounded host app keeps rendering. In that state we measured 207 unacknowledged batches accumulating over a 39-minute background period, each retaining its TaskCompletionSource plus everything registered against it (updated-component id arrays, cloned disposed-event-handler ids, _eventBindings entries) until acknowledged.

This ports the backpressure RemoteRenderer already applies for the equivalent scenario in Blazor Server:

  • ProcessPendingRender() skips producing a new batch while the unacknowledged queue is at capacity. Pending renders stay coalesced in the base renderer's render queue, so retained state is bounded.
  • NotifyRenderCompleted produces any deferred renders once an acknowledgement frees a slot.

The cap is an internal constant matching the default of CircuitOptions.MaxBufferedUnacknowledgedRenderBatches (10), so there is no new public API. Happy to make it configurable (the WebView equivalent of CircuitOptions) if that's preferred.

Two unit tests cover the behavior via TestWebViewManager: batches stop at the cap while acknowledgements are withheld (previously 21 batches were sent, unbounded), and the deferred renders flush as a single batch once one is acknowledged. TestWebViewManager gained a ReceiveRenderCompletedMessage helper mirroring ReceiveAttachPageMessage.

Notes:

Fixes #68675

Copilot AI lite review requested due to automatic review settings August 24, 2026 08:30
@Kebechet
Kebechet requested a review from a team as a code owner August 24, 2026 08:30
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Aug 24, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Thanks for your PR, @Kebechet. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds backpressure to Blazor WebView rendering so WebViewRenderer stops producing new render batches when too many are outstanding (unacknowledged), resuming once acknowledgements arrive. It also includes an unrelated addition of a new ComponentBase protected API (IsAfterInitialization) with corresponding test and API-surface updates.

Changes:

  • Add a cap (MaxBufferedUnacknowledgedRenderBatches) and gate ProcessPendingRender() to prevent unbounded accumulation of unacknowledged render batches in WebViewRenderer.
  • Resume deferred rendering when a batch acknowledgement is received (NotifyRenderCompleted triggers ProcessPendingRender).
  • Add tests/helpers for the WebView backpressure behavior, and separately add ComponentBase.IsAfterInitialization + tests + PublicAPI updates.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Components/WebView/WebView/src/Services/WebViewRenderer.cs Adds backpressure by gating rendering when the unacknowledged-batch queue reaches a fixed cap, and resumes on acknowledgement.
src/Components/WebView/WebView/test/WebViewRendererTests.cs New unit tests validating that render batches stop at the cap and resume (flushing deferred work) after an acknowledgement.
src/Components/WebView/WebView/test/Infrastructure/TestWebViewManager.cs Adds a ReceiveRenderCompletedMessage helper to drive acknowledgement behavior in tests.
src/Components/Components/src/ComponentBase.cs Adds a new protected lifecycle-state property IsAfterInitialization and renames the internal init-tracking field.
src/Components/Components/test/ComponentBaseTest.cs Adds unit tests covering the new IsAfterInitialization behavior under sync init, async init, cancellation, and exceptions.
src/Components/Components/src/PublicAPI.Unshipped.txt Records the new ComponentBase.IsAfterInitialization protected API surface addition.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +45 to +48
/// <summary>
/// Indicates if the component finished calling the <see cref="OnInitialized"/> and <see cref="OnInitializedAsync"/>.
/// </summary>
protected bool IsAfterInitialization { get; private set; }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — those ComponentBase commits were unrelated local WIP that ended up under the branch by mistake. Removed by rebasing onto upstream/main; the PR now only contains the WebViewRenderer change and its tests.

Comment on lines +45 to +48
/// <summary>
/// Indicates if the component finished calling the <see cref="OnInitialized"/> and <see cref="OnInitializedAsync"/>.
/// </summary>
protected bool IsAfterInitialization { get; private set; }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was included by mistake and is no longer part of the PR (see the sibling thread).

…ueue

Stop producing new render batches while the client has too many
unacknowledged ones, mirroring RemoteRenderer.ProcessPendingRender and
the default of CircuitOptions.MaxBufferedUnacknowledgedRenderBatches.
Rendering resumes when a batch gets acknowledged.
@Kebechet
Kebechet force-pushed the webview-renderer-backpressure branch from 5bce4a0 to e560e26 Compare August 24, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Blazor Hybrid] WebViewRenderer applies no backpressure — unacknowledged render batches accumulate without bound

2 participants