Skip to content

[Perf] Reuse ElementEventArgs in tree propagation#34134

Merged
PureWeen merged 2 commits intonet11.0from
dev/simonrozsival/reuse-element-eventargs
Mar 30, 2026
Merged

[Perf] Reuse ElementEventArgs in tree propagation#34134
PureWeen merged 2 commits intonet11.0from
dev/simonrozsival/reuse-element-eventargs

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

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!

Fixes #34093

Description

OnDescendantAdded and OnDescendantRemoved allocate a new ElementEventArgs at every tree level during parent propagation. This creates O(depth) allocations per child add/remove. This PR creates the ElementEventArgs once at the entry point and passes it up through the recursive walk.

@simonrozsival simonrozsival added perf/general The issue affects performance (runtime speed, memory usage, startup time, etc.) (sub: perf) copilot labels Feb 19, 2026
@simonrozsival simonrozsival marked this pull request as ready for review February 19, 2026 13:29
Copilot AI review requested due to automatic review settings February 19, 2026 13:29
@simonrozsival simonrozsival changed the title [WIP][Perf] Reuse ElementEventArgs in tree propagation [Perf] Reuse ElementEventArgs in tree propagation Feb 19, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves Microsoft.Maui.Controls.Element descendant add/remove event propagation performance by reusing a single ElementEventArgs instance while walking up the parent chain, instead of creating new args at each propagation step.

Changes:

  • Create ElementEventArgs once in OnDescendantAdded(Element)/OnDescendantRemoved(Element) and pass it through a new helper overload during parent propagation.
  • Update propagation to call RealParent?.OnDescendantAdded(args) / RealParent?.OnDescendantRemoved(args) to avoid repeated allocations while walking ancestors.

Comment on lines 961 to 965
void OnDescendantAdded(ElementEventArgs args)
{
DescendantAdded?.Invoke(this, args);
RealParent?.OnDescendantAdded(args);
}
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

Introducing an overload OnDescendantAdded(ElementEventArgs args) makes it easy to accidentally call the allocating OnDescendantAdded(Element child) in future edits, and it’s less discoverable that one overload is the non-allocating propagation helper. Consider renaming the helper overload to something like OnDescendantAddedCore/OnDescendantRemovedCore for clarity and consistency with other *Core helper patterns in this file.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@StephaneDelcroix StephaneDelcroix left a comment

Choose a reason for hiding this comment

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

LGTM from my review. I don't see blocking issues; this looks good to merge as-is.

@PureWeen
Copy link
Copy Markdown
Member

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

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@StephaneDelcroix StephaneDelcroix force-pushed the dev/simonrozsival/reuse-element-eventargs branch from a4c8314 to 2017c13 Compare February 27, 2026 13:53
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 27, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34134

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34134"

@StephaneDelcroix StephaneDelcroix force-pushed the dev/simonrozsival/reuse-element-eventargs branch from 2017c13 to bafb9b8 Compare February 27, 2026 19:20
@simonrozsival simonrozsival force-pushed the dev/simonrozsival/reuse-element-eventargs branch from bafb9b8 to c9b26a2 Compare March 11, 2026 09:32
simonrozsival and others added 2 commits March 20, 2026 10:07
Fixes #34093

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Defer ElementEventArgs creation until first non-null subscriber
- Zero allocations when no DescendantAdded/Removed handlers exist
- Rename recursive helpers to OnDescendantAddedCore/RemovedCore

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival force-pushed the dev/simonrozsival/reuse-element-eventargs branch from fd585e0 to 13fcf8b Compare March 20, 2026 09:08
@simonrozsival
Copy link
Copy Markdown
Member Author

@PureWeen @mattleibow could you please have a look at this PR and let me know what you think about it? could we merge this into net11.0 soon?

@simonrozsival
Copy link
Copy Markdown
Member Author

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

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@PureWeen PureWeen merged commit 214eaf9 into net11.0 Mar 30, 2026
35 of 44 checks passed
@PureWeen PureWeen deleted the dev/simonrozsival/reuse-element-eventargs branch March 30, 2026 15:03
simonrozsival added a commit that referenced this pull request Mar 31, 2026
Remove '?' from ElementEventArgs parameters in OnDescendantAddedCore
and OnDescendantRemovedCore. The file has '#nullable disable' at the
top, so nullable reference type annotations are invalid and cause
CS8632 warnings which become errors when TreatWarningsAsErrors=true
(e.g. in dotnet/android CI).

Introduced in #34134.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
StephaneDelcroix pushed a commit that referenced this pull request Mar 31, 2026
…t in Element.cs (#34751)

<!-- 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!

## Description

Removes `?` nullable annotations from `ElementEventArgs` parameters in
`OnDescendantAddedCore` and `OnDescendantRemovedCore` in `Element.cs`.

The file starts with `#nullable disable`, so nullable reference type
annotations are invalid and produce **CS8632** warnings. MAUI CI sets
`TreatWarningsAsErrors=false` so these pass silently, but downstream
consumers like **dotnet/android** build with
`TreatWarningsAsErrors=true`, causing build failures.

Introduced in #34134.

## Fix

Simply remove the `?` from the `ElementEventArgs` parameter types. Under
`#nullable disable`, reference types are already implicitly nullable, so
the behavior is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot perf/general The issue affects performance (runtime speed, memory usage, startup time, etc.) (sub: perf)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants