It would appear that AOT compilation gets substantial performance improvements in client-side application performance.
I put together a tech demo running Blazor client side WASM. The code for the main component is at the bottom of this post.
The gist is this: draw an image, using the SixLabors ImageSharp library, 20 times. Each image is slightly wider than the previous, and post the time taken.
In my experiments, it takes about 1/3rd as much time to complete with Ahead-of-time compilation.
Here's the test without AOT compilation:
And the same test, compiled with AOT:
Obviously, this is an anecdotal test, but it would certainly appear to me that AOT compilation can make for some very fast client-side image processing applications.
Code below:
@page "/"
@using SixLabors.ImageSharp
@using SixLabors.ImageSharp.Drawing
@using SixLabors.ImageSharp.Drawing.Processing
@using SixLabors.ImageSharp.Formats.Jpeg
@using SixLabors.ImageSharp.Formats.Png
@using SixLabors.ImageSharp.PixelFormats
@using SixLabors.ImageSharp.Processing
@using System.Diagnostics
<PageTitle>Home</PageTitle>
<h1>Blazor WASM AOT performance testing</h1>
<button @onclick="_ => StartWork()" disabled="@started">Start</button>
<p>milliseconds to @TOTAL_ITERATIONS draws: @TimeTaken</p>
<img src="@ImgString" />
@code {
const int TOTAL_ITERATIONS = 20;
private string? ImgString { get; set; }
private long TimeTaken { get; set; }
private int TimesCompleted { get; set; }
private bool started { get; set; } = false;
private Stopwatch Timer { get; set; } = new Stopwatch();
private async Task StartWork()
{
started = true;
TimesCompleted = 1;
Timer.Start();
while(TimesCompleted < TOTAL_ITERATIONS)
{
await DrawStar();
}
Timer.Stop();
TimeTaken = Timer.ElapsedMilliseconds;
}
private async Task DrawStar()
{
using (Image<Rgba32> image = new(TimesCompleted * 10, 200))
{
Star star = new(x: 100.0f, y: 100.0f, prongs: 5, innerRadii: 20.0f, outerRadii: 30.0f);
image.Mutate(x => x.Fill(Color.Red, star));
ImgString = image.ToBase64String(JpegFormat.Instance);
}
TimesCompleted++;
StateHasChanged();
await Task.Delay(100);
Console.WriteLine(this.ImgString);
}
}