Find what slows .NET startup (Beta)

Investigate startup time and runtime work in .NET Android and iOS apps using CPU, call-tree, GC, JIT, exception, and thread evidence.

Profiling helps you see where your app spends time before its first usable screen and during the captured run. Use startup milestones, CPU samples, call trees, and runtime events to investigate the work behind a slow launch.

Beta feature. Profiling commands and the preparation package are experimental and may change before general availability. Profiling commands are omitted from default CLI help; run ansight help --beta to include them.

Add Ansight.Profiling.DotNet to your app before building it. In a profiling build, the package configures .NET diagnostics and embeds the target manifest that the CLI checks before launch. Your app also uses the package to report when it is ready for interaction.

Build and sign the app using your normal project workflow, then give the resulting artifact to the CLI to capture and analyze its launch.

Install and Enable

Add the package to the app project:

dotnet add package Ansight.Profiling.DotNet

Enable profiling in a dedicated development configuration. This example uses an Android emulator; choose the target that matches the device you will profile:

<PropertyGroup Condition="'$(Configuration)' == 'Profile'">
  <AnsightProfilingEnabled>true</AnsightProfilingEnabled>
  <AnsightProfilingTarget>android-emulator</AnsightProfilingTarget>
</PropertyGroup>

Supported targets are:

  • android-emulator
  • android-device
  • ios-simulator
  • ios-device

Call ApplicationReady() when your app is ready for interaction, such as when its first usable screen is ready. This gives startup analysis an explicit end point defined by your app:

using Ansight.Profiling;

AnsightProfiler.ApplicationReady();

The first call emits StartupComplete from the Ansight-DotNet-Startup EventSource when tracing is active; later calls are ignored. This records the point you chose, not an automatic measurement of the first rendered frame.

Build the profiling app

Build the app with the profiling configuration enabled, using the signing and packaging steps required by your project. The CLI accepts the resulting .app, .apk, or .ipa; it does not build or sign the app for you.

The build embeds ansight/dotnet-profiling.json. Its target must match the simulator, emulator, or physical device selected for capture. Rebuild with the appropriate AnsightProfilingTarget when switching target types.

Capture

Check the tracing tools, then start a capture with the built artifact, its package or bundle identifier, and the target device ID:

ansight profile dotnet tools
ansight profile dotnet start ./MyApp.apk \
  --app-id com.example.myapp \
  --device-id emulator-5554 \
  --duration-seconds 30 \
  --wait

Replace the example path and IDs with your app and device. --wait keeps the command attached until the capture finishes; copy the capture ID from its result. Use --symbols to retain portable PDBs with the capture when symbolication requires them.

Analyze

Start with overview to check what was captured, then startup to inspect the launch milestones. Replace <capture-id> with the ID returned by the capture. Use the remaining commands to examine CPU activity, call stacks, threads, garbage collection, JIT compilation, or exceptions:

ansight profile dotnet overview <capture-id>
ansight profile dotnet startup <capture-id>
ansight profile dotnet cpu <capture-id>
ansight profile dotnet call-tree <capture-id>
ansight profile dotnet threads <capture-id>
ansight profile dotnet gc <capture-id>
ansight profile dotnet jit <capture-id>
ansight profile dotnet exceptions <capture-id>
ansight profile dotnet speedscope <capture-id>

In the startup output, look for the application-ready milestone. If no marker was captured, analysis shows runtime milestones and uses trace boundaries as a startup proxy. Capture timings include tracing and launch overhead.

Analysis commands support time-window and process/thread filters. See the CLI command reference for every capture and analysis option.