Install
dotnet add package Plugin.Maui.Performance
dotnet tool install -g Plugin.Maui.Performance.CliPackage ID: Plugin.Maui.Performance. Current NuGet is 1.0.7. The CLI tool is optional — install it only when you want maui-perf aliases over raw maui profile flags. Both PackageIds publish from the same repo CI.
Restore Plugin.Maui.* from GitHub Packages: Use nuvyntralabs GitHub Packages from a C# project
Register
using Plugin.Maui.Performance;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiPerformance();
return builder.Build();
}
}Registration starts automatic startup, page, navigation, image, and render measurement. On Android it also hooks OnResume; on iOS it hooks OnActivated.
Named traces and the report
using var trace = MauiPerformance.Trace("LoadCustomer");
await MauiPerformance.MeasureAsync("Customer API", () => client.GetStringAsync("/customer"), PerformanceCategory.Api);
MauiPerformance.Measure("SQLite Query", () => db.Query("SELECT * FROM customer"), PerformanceCategory.Database);
Console.WriteLine(MauiPerformance.FormatReport());Automatic API tracking
builder.Services.AddHttpClient("shop", client =>
{
client.BaseAddress = new Uri("https://api.shop");
}).AddHttpMessageHandler(() => new PerformanceDelegatingHandler());Override the metric name per request. Query strings are stripped from stored URLs.
var request = new HttpRequestMessage(HttpMethod.Get, "/customer");
request.Options.Set(PerformanceHttp.NameKey, "Customer API");Android HTTP tracking needs INTERNET and ACCESS_NETWORK_STATE. iOS needs no extra Info.plist keys.
Stop maui profile from the app
builder.UseMauiPerformance(options =>
{
options.CliProfile.CompleteOn = CliProfileCompleteOn.FirstFrame;
// options.CliProfile.CompleteOnScenario = "Checkout";
});
using var checkout = MauiProfile.Scenario("Checkout");
MauiProfile.Mark("CartReady");
// dispose / Complete() records a metric and can stop the CLI sessionFirstFrame is the default. Use FirstPage for the App Startup moment, Manual to call StartupComplete() yourself, or CompleteOnScenario to wait for a named flow.
maui-perf at the command line
Install the companion tool, then use short aliases instead of the long official flags. startup always passes Microsoft.Maui.ProfilingHelper / StartupComplete so the trace ends when first frame (or your scenario) fires. screen wraps maui profile manual (press Enter to attach, Enter again to stop).
dotnet tool install -g Plugin.Maui.Performance.Cli
maui-perf startup -f android
maui-perf screen -f ios --speedscope --duration 30s
maui-perf command startup -f androidFrom a clone of this repo without installing the tool:
dotnet run --project src/Plugin.Maui.Performance.Cli -- startup -f android| Option | Meaning |
|---|---|
| -f android | ios | Framework alias for net10.0-android / net10.0-ios. |
| --duration 30s | 2m | 1h | Parsed duration for screen / manual. |
| --speedscope | Shortcut for --format speedscope (also nettrace, mibc). |
| --no-stop-marker | Do not pass StartupComplete stopping events. |
| --dry-run / command | Print the maui profile command without running it. |
maui-perf is a shorter wrapper. Install the MAUI CLI so the maui command is on PATH. Official maui profile documentation
Options
builder.UseMauiPerformance(options =>
{
options.AutoMeasureStartup = true;
options.AutoMeasurePages = true;
options.AutoMeasureNavigation = true;
options.AutoMeasureImages = true;
options.AutoMeasureRendering = true;
options.SampleMemory = true;
options.Enabled = true;
});Without the generic host
var performance = MauiPerformance.Create(new MauiPerformanceOptions
{
AutoMeasureStartup = true
});
performance.Start();Compose with siblings
Performance does not reference Diagnostics, LeakAnalyser, or Observability. Wire them yourself when the host already uses those plugins. Treat a slow page as a metric, not a crash.
builder
.UseMauiApp<App>()
.UseMauiPerformance()
.UseMauiDiagnostics();
MauiPerformance.Current.MetricRecorded += (_, e) =>
{
if (e.Metric.Duration >= TimeSpan.FromSeconds(2))
MauiDiagnostics.TrackEvent($"Slow:{e.Metric.Name}");
};What not to wire
| Temptation | Why not |
|---|---|
| This package as a leak detector | Use LeakAnalyser for WeakReference liveness after pop. |
| This package as crash / ANR capture | Use Diagnostics. |
| Microsoft.Maui.ProfilingHelper package reference | maui profile injects the helper; MauiProfile calls Complete() for you. |
| maui-perf on Windows / Mac Catalyst | maui profile supports Android and iOS simulator only. |
| A hosted APM just to print a scoreboard | Use FormatReport() on device. |
| Package reference Performance → Diagnostics | Keeps the profiler usable without the telemetry suite. |