[android] improve performance of `ImageHandler.PlatformArrange()`
Context: https://github.com/davidortinau/AllTheLists
Profiling @davidortinau's app, I noticed the "Check-ins" sample felt the slowest on Android.
One thing I noticed while scrolling:
98.75ms (0.90%) Microsoft.Maui!Microsoft.Maui.Handlers.ImageHandler.PlatformArrange(Microsoft.Maui.Graphics.Rect)
67.11ms (0.61%) Mono.Android!Android.Widget.ImageView.ScaleType.get_CenterCrop()
In this case, PlatformArrange() is called a lot for every <Image/>:
if (PlatformView.GetScaleType() == ImageView.ScaleType.CenterCrop)
{
var (left, top, right, bottom) = PlatformView.Context!.ToPixels(frame);
var clipRect = new Android.Graphics.Rect(0, 0, right - left, bottom - top);
PlatformView.ClipBounds = clipRect;
}
ImageView.ScaleType is a class, and so and some bookkeeping is done to lookup the same C# instance for a Java object. We can make this a bit better by writing a new Java method:
public static boolean isImageViewCenterCrop(@NonNull ImageView imageView) {
return imageView.getScaleType() == ImageView.ScaleType.CENTER_CROP;
}
Next, let's make a PlatformView.ToPixels() extension method that can avoid calling View.Context for the same reason.
Lastly, we can make a PlatformInterop.SetClipBounds() method to avoid creating a Android.Graphics.Rect object in C#.
With these changes, I can only see the topmost PlatformArrange() method now:
2.93ms (0.03%) Microsoft.Maui!Microsoft.Maui.Handlers.ImageHandler.PlatformArrange(Microsoft.Maui.Graphics.Rect)
This should improve the layout performance of all .NET MAUI <Image/> on Android. I also "banned" GetScaleType() in eng/BannedSymbols.txt.
This broke one test, I think I should see a doggo:
I want to share some of the Java.Lang.Enum weirdness here with Jon Pryor when he returns from vacation.
I'll come back to this.
Is this going into next SR? Seems like a great adition!
Any news on this?
Sorry to bump this, but feels like this is an important MR to improve performance overall in a basic element like Image in all applications
@bcaceiro I originally held off on this because it could be fixed here:
- https://github.com/dotnet/java-interop/pull/1248
- https://github.com/dotnet/java-interop/issues/1243
We'll try to merge it now, as those changes didn't land.