.NET MAUI Performance Optimization
Profiling
-
dotnet-trace: Cross-platform profiler for all MAUI targets. Collect traces with: dotnet-trace collect --process-id <PID> --providers Microsoft-DotNETCore-SampleProfiler
-
PerfView (Windows only): Use for deep allocation and CPU analysis on WinUI targets.
-
Profile before optimizing — measure, don't guess.
Compiled Bindings
-
Always set x:DataType on pages/views to enable compiled bindings.
-
Compiled bindings are 8–20× faster than reflection-based bindings.
-
Required for NativeAOT and full trimming — reflection bindings break under trimming.
-
Apply x:DataType at the highest reasonable scope (page or root element).
<ContentPage xmlns:vm="clr-namespace:MyApp.ViewModels" x:DataType="vm:MainViewModel"> <Label Text="{Binding Title}" /> </ContentPage>
- For DataTemplate inside CollectionView /ListView , set x:DataType on the template root:
<DataTemplate x:DataType="model:Item"> <Label Text="{Binding Name}" /> </DataTemplate>
- Minimize unnecessary bindings: Static content that never changes doesn't need {Binding} . Use literal values or x:Static instead.
Layout Optimization
-
Avoid nested single-child layouts — a StackLayout with one child is pointless overhead.
-
Prefer Grid over nested StackLayout /VerticalStackLayout — Grid resolves layout in a single pass.
-
Use IsVisible="False" to hide elements rather than adding/removing from the tree at runtime.
-
Remove unnecessary wrapper containers — every layout adds a measure/arrange pass.
-
Avoid AbsoluteLayout when Grid with row/column definitions achieves the same result.
-
Set explicit WidthRequest /HeightRequest where sizes are known to reduce measure passes.
CollectionView and ListView
- Use ItemSizingStrategy="MeasureFirstItem" on CollectionView when items have uniform height — avoids measuring every item individually.
<CollectionView ItemSizingStrategy="MeasureFirstItem" ItemsSource="{Binding Items}">
-
Prefer CollectionView over ListView for new development.
-
Keep DataTemplate visual trees shallow — fewer nested layouts per item.
Image Optimization
-
Size images to display resolution — don't load a 4000×3000 image for a 200×200 display.
-
Use Aspect="AspectFill" or AspectFit and set explicit dimensions.
-
Cache downloaded images: CachingEnabled="True" (default) on UriImageSource , set CacheValidity .
-
Use platform-appropriate formats (WebP for Android, HEIF/PNG for iOS).
-
For icons and simple graphics, prefer SVG or vector-based font icons.
Resource Dictionaries
-
App-level (App.xaml ): Shared styles, colors, converters used across multiple pages.
-
Page-level: Styles/resources specific to a single page — keeps App.xaml lean.
-
Avoid duplicating resources across dictionaries.
-
Use MergedDictionaries to organize large resource sets without bloating a single file.
Startup Optimization
-
Minimize work in App constructor and MainPage constructor.
-
Defer non-essential service registration — use lazy initialization where possible.
-
Reduce the number of XAML pages parsed at startup (use Shell routing for deferred loading).
-
Remove unused Handlers /Effects registrations from MauiProgram.cs .
-
On Android, ensure AndroidManifest.xml doesn't force unnecessary permissions checks at launch.
Trimming
Enable IL trimming to reduce app size and remove unused code:
<PropertyGroup> <PublishTrimmed>true</PublishTrimmed> <TrimMode>full</TrimMode> </PropertyGroup>
-
Test thoroughly — trimming can remove code accessed only via reflection.
-
Use [DynamicDependency] or [UnconditionalSuppressMessage] to preserve reflection targets.
-
Compiled bindings are essential — reflection-based bindings will be trimmed away.
NativeAOT
-
NativeAOT compiles to native code ahead-of-time for faster startup and smaller footprint.
-
Requirements: compiled bindings, no unconstrained reflection, trimming-compatible code.
<PropertyGroup> <PublishAot>true</PublishAot> <PublishTrimmed>true</PublishTrimmed> </PropertyGroup>
-
Audit third-party NuGet packages for trimming/AOT compatibility.
-
Use [JsonSerializable] source generators instead of reflection-based JSON serialization.
-
Run dotnet publish with AOT to verify no warnings before shipping.
Quick Checklist
-
✅ x:DataType on all pages, templates, and data-bound views
-
✅ No nested single-child layouts
-
✅ Grid preferred over nested StackLayouts
-
✅ Images sized to display, caching enabled
-
✅ ItemSizingStrategy="MeasureFirstItem" on uniform CollectionViews
-
✅ Startup work minimized and deferred
-
✅ Trimming enabled and tested
-
✅ Profile with dotnet-trace before and after changes