dotnet / dotnet/maui

[Perf] Native handler creation for modest visual trees is prohibitively slow — 50 Labels / 50 composite fields freeze UI for seconds on low-end Windows and Android

Open
#38,531 0 comments 1 reaction 0 assignees View on GitHub
t/bug
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

### Description

In .NET MAUI 9, constructing a dense but realistic form (30–50 fields, no CollectionView virtualization) is dominated by per-element native handler creation (MAUI → WinUI / Android view), not by XAML parsing, layout container choice, or our layout algorithm.

This is blocking for enterprise field software: survey forms must show all fields at once, using custom AbsoluteLayout positioning. CollectionView virtualization is not applicable because there is no scroll window that can defer creation.

A standalone repro (MauiLayoutMetrics) isolates the cost. Even 50 plain Labels is already slow on low-end hardware. A production-shaped StringField (~24 visual elements, depth ~9) becomes ~1,200 platform views for 50 fields.

Painting the same 50 fields with one GraphicsView + IDrawable is orders of magnitude faster. That is not a viable replacement for interactive forms: we still need native Entry for IME/caret. We should not have to abandon the control model to get acceptable first-paint.

Related: [#17303](https://github.com/dotnet/maui/issues/17303), [#34088](https://github.com/dotnet/maui/issues/34088) (PropertyMapper work on handler connect). This issue is the user-visible scale: handler connect cost × hundreds of views on constrained devices.

### Steps to Reproduce

Attached sample application to get the performance metrics.
Steps to reproduce
Build and run the attached sample Release:
dotnet run -c Release --framework net9.0-windows10.0.19041.0
(or net9.0-android on the TSC5-class device)

Test 6: Diagnostic – Where Is The Cost?
Run A → E in order (Clear between runs). Each creates 50 items.
Test Visual tree
A
50 Label
B
50 × (Border > Label)
C
50 × (Grid > Label + Border > Label) — no ContentView
D
50 × lightweight field (~5 elements, ContentView)
E
50 × full StringField (~24 elements)
Test 13: Full TextField Compare — same 50 fields, five strategies, timed Instantiation / Layout / Total:
Strategy Native views (approx.)
Form IDrawable
1 GraphicsView (+ hidden Entry overlay)
Per-field GraphicsView
50–100
Full XAML StringField
~1,200
Lightweight StringField
~250
MDC TextField
50 GraphicsViews
Optional: Test 1 (static XAML) vs Test 2 (dynamic AbsoluteLayout) vs Test 7 (single IDrawable). Static XAML is not faster; XamlC emits the same new + handler path.

Record create ms and total ms from the on-screen labels
[MauiLayoutMetrics.zip](https://github.com/user-attachments/files/32194412/MauiLayoutMetrics.zip)

### Link to public reproduction project repository

_No response_

### Version with bug

9.0.110 SR12

### Is this a regression from previous behavior?

Not sure, did not test other versions

### Last version that worked well

Unknown/Other

### Affected platforms

Windows, Android

### Affected platform versions

_No response_

### Did you find any workaround?

We are currently replacing an existing Qt-based application with .NET MAUI. As part of this migration, we are using .NET MAUI GraphicsView for rendering the application's graphics-intensive UI.

One of the major challenges we are facing is rendering and overall UI performance on low-end hardware devices. The existing Qt application provides smooth and responsive rendering on these devices, while the equivalent implementation using MAUI GraphicsView shows noticeable performance degradation.

Our goal is to achieve performance comparable to the existing Qt implementation, particularly on low-end hardware, so that the migration to MAUI does not result in a degraded user experience.

Current Challenges
The GraphicsView implementation is relatively complex and involves graphics-intensive rendering operations. The performance impact becomes more significant when:

A large number of graphical elements need to be rendered.
The UI requires frequent redraws or updates.
Multiple graphical objects are updated simultaneously.
Complex shapes, paths, transformations, or other drawing operations are involved.
Rendering needs to happen continuously or at a high frequency.
The application is running on low-end hardware with limited CPU/GPU capabilities.
Compared with the existing Qt implementation, the MAUI implementation requires significantly more optimization to maintain the same level of responsiveness and rendering performance.

Expected Outcome
We need to investigate and identify the performance bottlenecks in the MAUI GraphicsView rendering pipeline and determine whether the current implementation can be optimized to achieve performance close to the Qt application.

The investigation should cover:

GraphicsView rendering and redraw behavior.
CPU/GPU utilization during rendering.
Frequency and cost of invalidation/redraw operations.
Memory allocation and garbage collection during rendering.
Performance of complex drawing operations.
Impact of rendering a large number of graphical elements.
Opportunities to minimize unnecessary redraws.
Hardware-specific performance differences, particularly on low-end devices.
Whether MAUI/GraphicsView has any inherent rendering limitations compared with the Qt rendering approach.
Acceptance Criteria
Identify the major performance bottlenecks in the current MAUI GraphicsView implementation.
Establish a reproducible performance benchmark comparing the MAUI implementation vs. the existing Qt implementation.
Measure rendering performance on representative low-end hardware.
Optimize the MAUI implementation where possible.
Minimize unnecessary redraws and rendering operations.
Achieve rendering responsiveness and frame performance as close as reasonably possible to the existing Qt application.
Document any remaining performance limitations that are caused by the MAUI/GraphicsView framework itself rather than application-level implementation.
If the required performance cannot be achieved through application-level optimization, evaluate alternative MAUI rendering approaches or framework-level improvements.
Context
This is a critical area for the ongoing Qt-to-.NET MAUI migration. The objective is not simply to make the MAUI implementation functional, but to ensure that the migrated application provides a comparable user experience and performance to the existing Qt application, especially on low-end hardware where the performance difference is currently most visible.

### Relevant log output

```shell

```

Contributor guide

Open the contributing guide

Research direction

Start by building and running the attached MauiLayoutMetrics sample in Release with the provided Windows or Android framework, then run Test 6 A–E and Test 13 while recording instantiation, layout, and total times. Compare the native-handler cases with the GraphicsView strategies and profile the rendering and handler paths. Done means the main bottlenecks are identified, reproducible benchmarks exist on low-end hardware, and feasible optimizations or framework limitations are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
desktop-dev, mobile-dev, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.