Skip to content

[Android] Fix scrolling performance in shadowed containers - #37291

Merged
kubaflo merged 1 commit into
dotnet:inflight/currentfrom
kubaflo:fix-37281-shadow-scroll
Aug 11, 2026
Merged

kubaflo merged 1 commit into
dotnet:inflight/currentfrom
kubaflo:fix-37281-shadow-scroll

Conversation

@kubaflo

@kubaflo kubaflo commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Root Cause

#35623 made PlatformWrapperView.onDescendantInvalidated() call invalidate() for every descendant update whenever the wrapper had a shadow. That keeps an immediate child animation such as a shadowed Switch in sync, but it also makes scrolling descendants redraw the entire shadowed container for every item update.

The complete reproduction from MrLazyLee/ScrollPerformance has two large shadow wrappers around the CollectionView:

  • The CommunityToolkit popup's default shadow.
  • An explicit shadow on the inner Border.

Instrumentation over four up/down scroll cycles recorded:

Wrapper Descendant invalidations Immediate-child invalidations
Popup, 1079 x 1678 1,859 3
Border, 1026 x 1306 1,803 2

The current code therefore forces thousands of full-popup redraws even though only five invalidations originate from the immediate children whose shadows may need to move.

Description of Change

Only invalidate a shadow wrapper when Android reports that the invalidation target is its immediate child (child == target). Deeper descendants continue to redraw through their own RenderNodes without forcing the whole shadowed ancestor to re-record its display list.

This preserves the #35623 behavior for controls such as Switch, while removing the scrolling regression for nested CollectionView and ScrollView content.

Verification

The author reproduction was built with the exact 10.0.90 source and the same locally-built native AAR for both control and patched runs. Each row below used the same emulator and automated eight-cycle scroll sequence without screen recording:

Variant 50th percentile 90th percentile Slow UI-thread frames
10.0.80 34 ms 53 ms 29
10.0.90 control 42-44 ms 53-61 ms 106-118
10.0.90 with this fix 34-38 ms 57-61 ms 28-47

The patched result returns to the 10.0.80 range. The Android Core View device-test category also passes: 76 run, 74 passed, 2 ignored, 0 failed. A focused test verifies that an immediate child still invalidates a shadow while a deeper descendant does not.

Videos

10.0.80 baseline

ScrollPerformance-10.0.80-evidence.mp4

10.0.90 regression

ScrollPerformance-10.0.90-regression.mp4

10.0.90 with this fix

ScrollPerformance-10.0.90-fixed.mp4

Issues Fixed

Fixes #37281

Regressed by #35623.

Limit shadow wrapper redraws to invalidations from the immediate child so scrolling descendants do not redraw entire shadowed containers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e5a1e61b-7ba7-4459-b224-6f22fc178755
@kubaflo
kubaflo temporarily deployed to copilot-pat-pool August 10, 2026 21:57 — with GitHub Actions Inactive
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@sheiksyedm

Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).

@kubaflo
kubaflo merged commit 58cb8ba into dotnet:inflight/current Aug 11, 2026
29 of 99 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR11 milestone Aug 11, 2026
@kubaflo

kubaflo commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

/backport to main

@kubaflo

kubaflo commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

/backport to release/10.0.1xx-sr10

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to main (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0.1xx-sr10 (link to workflow run)

kubaflo added a commit that referenced this pull request Aug 11, 2026
…ed containers (#37312)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

Backport of #37291 to `release/10.0.1xx-sr10`.

/cc @kubaflo

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Aug 11, 2026
…7313)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

Backport of #37291 to `main`.

/cc @kubaflo

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
@kubaflo kubaflo modified the milestones: .NET 10 SR11, .NET 10 SR10 Aug 11, 2026
@sheiksyedm sheiksyedm modified the milestones: .NET 10 SR10, .NET 10 SR11 Aug 26, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 25, 2026

This branch was previously deployed

1 inactive deployment
copilot-pat-pool — ba8cc2e4 Deployed Aug 10, 2026 by kubaflo via conclusion #1232
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Scrolling inside shadowed containers regressed in 10.0.90

2 participants