-
Notifications
You must be signed in to change notification settings - Fork 3
Layout Diagnostics
A runtime diagnostics tool for profiling .NET MAUI layout performance on iOS and Android. It captures per-element measure and arrange counts during page navigation and bottom sheet presentation, helping developers identify layout thrashing — views that are measured or arranged far more than necessary.
.NET MAUI's layout system uses a two-phase process for every frame where layout is needed (source):
-
Measure phase — The framework calls
IView.Measure()on each view to determine its desired size given constraints. Layouts callMeasure()on all their children recursively, bottom-up. -
Arrange phase — The framework calls
IView.Arrange()on each view to assign its final position and bounds within the parent layout.
These phases can be triggered multiple times per frame. A parent layout may speculatively measure children, change constraints, and re-measure. Deeply nested layouts with complex constraints can cause exponential measure/arrange calls — known as layout thrashing.
Layout Diagnostics hooks into MAUI's built-in System.Diagnostics.Metrics instruments (maui.layout.measure_count, maui.layout.arrange_count) via MeterListener to count every measure and arrange call per element type and instance.
Register metrics in MauiProgram.cs before .UseMauiApp<App>():
builder.Services.AddMetrics(); // Microsoft.Extensions.Diagnostics// Show the floating overlay (dormant — not yet recording)
LayoutDiagnosticsService.Initialize();| Member | Description |
|---|---|
Initialize() |
Shows the floating overlay pill |
Teardown() |
Removes the overlay and tears down the system |
Enable() |
Starts capturing layout metrics |
Disable() |
Stops capturing, returns all snapshots |
Toggle() |
Toggles between Enable/Disable |
ClearSnapshots() |
Clears all completed snapshots |
ExportAllToJson() |
Exports all snapshots as a JSON string |
IsEnabled |
Whether diagnostics are currently capturing |
IsInitialized |
Whether the overlay has been initialized |
CompletedSnapshots |
All snapshots captured during this session |
CurrentSnapshot |
The in-progress snapshot (null if none) |
SnapshotCompleted |
Event raised when a snapshot finishes |
Snapshots are automatically created and ended during page and bottom sheet lifecycle:
-
ContentPage.OnAppearing()→BeginSnapshot("Page: {TypeName}") -
ContentPage.OnNavigatingFrom()→EndSnapshot() -
BottomSheet.OnAppearing()→BeginSnapshot("BottomSheet: {TypeName}") -
BottomSheet.OnDisappearing()→EndSnapshot()
Each LayoutDiagnosticsSnapshot contains:
-
SourceName— What triggered it (e.g., "Page: HomePage") -
TotalMeasureCount/TotalArrangeCount— Aggregate counts -
MeasureCountsByType/ArrangeCountsByType— Per-type breakdown (e.g.,"Microsoft.Maui.Controls.Label": 45) -
MeasureInstancesByType— Unique instances per type, enabling per-instance averages -
Warnings— Types exceeding an average of 3 layout passes per instance
| Metric | Healthy | Investigate |
|---|---|---|
| Avg measures per instance | 1–2× | > 3× (flagged with |
| Total measures for a page | < 200 | > 500 |
Common causes of high measure counts:
- Deeply nested layouts (Grid inside StackLayout inside ScrollView)
-
Auto-sized rows/columns that cause re-measure cascades - Changing
IsVisibleorTexton elements during layout
The diagnostics overlay is a floating pill that stays visible over all content, including modals and bottom sheets:
-
iOS: Rendered in a separate
UIWindowatUIWindowLevel.Alert - 1with touch passthrough viaHitTestoverride -
Android: Re-parented to the dialog
DecorViewwhen dialogs open, managed viaFragmentLifeCycleCallback
Tap the pill to expand and see live recording status, start/stop controls, and the current snapshot summary.
Inspect the LayoutDiagnosticsService and LayoutDiagnosticsSnapshot classes for the full API surface.
Components
- Buttons
- Checkboxes
- Chip
- CollectionView
- Content control
- Context Menus
- Counters
- Divider
- Labels
- ListItem
- Pickers
- SaveView
- SortControl
- Tag
- TextFields
- Toolbar
Feedback & State
Guides
- Displaying code inside a mobile app
- Layout Diagnostics
- Memory Leaks
- Performance
- Providing help in your app
Interaction & Accessibility
Layout & Navigation
Media
Styling & Resources