| name | maui-performance |
| description | Performance optimization guidance for .NET MAUI apps covering profiling, compiled bindings, layout efficiency, image optimization, resource dictionaries, startup time, trimming, and NativeAOT configuration. USE FOR: "performance optimization", "slow startup", "app performance", "compiled bindings", "layout optimization", "image optimization", "trimming", "NativeAOT", "profiling MAUI", "reduce app size", "startup time". DO NOT USE FOR: data binding syntax (use maui-data-binding), deprecated API migration (use maui-current-apis), or unit testing setup (use maui-unit-testing).
|
.NET MAUI Performance Optimization
Profiling
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