Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image

Do you use SVG images? In this article, I’m going to compare FFImageLoading.Svg.Forms vs Xamarin.Forms.Image performance.I love the FFImageLoading plugin. Because it’s super easy to use, it’s known probably by every Xamarin developer, it has built-in f…


This content originally appeared on Level Up Coding - Medium and was authored by Aleksei Starkov

Do you use SVG images? In this article, I’m going to compare FFImageLoading.Svg.Forms vs Xamarin.Forms.Image performance.

I love the FFImageLoading plugin. Because it’s super easy to use, it’s known probably by every Xamarin developer, it has built-in features like transformations and caching. Because of that when it comes to embedded SVG images, an answer might be obvious: FFImageLoading.Svg.Forms. However, is it a good idea to use our lovely plugin for embedded vector graphics? So let’s check it comparing FFImageLoading.Svg.Forms vs Xamarin.Forms.Image performance.

Why we need it?

There are a lot of things that make a mobile application user unhappy. A problem might be caused by a backend, bugs, poor UI/UX, or …. performance. Unlike backend or UI/UX that might be out of mobile developer control, the performance of a mobile application is our responsibility and something we have to take care of. When it comes to navigation between pages, probably the most annoying problem for a user is page rendering speed. Let’s imagine a user pushing a button to navigate to another page. The last thing which a user expects is unresponsiveness or delay. That is why it’s important to keep performance in mind and follow good practices. However, there is an inconspicuous thing that can involve page rendering speed significantly — images and icons rendering speed.

How to measure FFImageLoading.Svg.Forms vs Xamarin.Forms.Image performance?

To measure the performance I’m going to add SVG images to a ContentPage to measure the time between page renderer creation and a moment when a content of the page became visible. After the page loading time will be measured for both platforms (iOS and Android) and both approaches (Xamarin.Forms.Image and FFImageLoading.Svg.Forms) it will be easy to see which way is faster.

Preparation

I’ll use Visual Studio 2019 for Mac as an IDE. I’ll also use two physical devices to make the measurement: iPhone SE2 (2020) and Samsung A5 2017. The images are also needed. So I got 15 SVG images of road signs from the internet.

Images to display

Step 1. Creating an application

Now let’s create a blank Xamarin.Forms application and add one more page with navigation to it. To show the measured time on the screen some label is needed. Finally, let’s install the FFImageLoading.Svg.Forms plugin and add the image controls to the StackLayout.

using Xamarin.Forms;  namespace _2_SVG_XFImage_vs_FFImageLoading 
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
}
<ContentPage
x:Class="_2_SVG_XFImage_vs_FFImageLoading.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Button
Clicked="OnButtonClicked"
Text="Navigate to Images Page"
VerticalOptions="Center" />
</ContentPage>
using System;
using _SVG_XFImage_vs_FFImageLoading;
using Xamarin.Forms;namespace _2_SVG_XFImage_vs_FFImageLoading
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
} private async void OnButtonClicked(Object sender, EventArgs e)
{
await Navigation.PushAsync(new ImagesPage());
}
}
}
Adding Xamarin.FFImageLoading.Svg.Forms plugin to Shared project
<ContentPage
x:Class="_SVG_XFImage_vs_FFImageLoading.ImagesPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffSvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="ffSvg:SvgCachedImage">
<Setter Property="Aspect" Value="AspectFit" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<StackLayout Spacing="10">
<Label
x:Name="measuredTimeLabel"
FontSize="Large"
HorizontalOptions="Center" />
<ffSvg:SvgCachedImage
Source="resource://arrowuparrowdownsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://bicyclesroadsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://crossingsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://dangerousbend.svg" />
<ffSvg:SvgCachedImage
Source="resource://horsesroadsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://nobicycles.svg" />
<ffSvg:SvgCachedImage
Source="resource://noentry.svg" />
<ffSvg:SvgCachedImage
Source="resource://payloadsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://roadlayoutsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://roadsignslippery.svg" />
<ffSvg:SvgCachedImage
Source="resource://tramroadsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://trucksign.svg" />
<ffSvg:SvgCachedImage
Source="resource://tunnelroadsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://warningsign.svg" />
<ffSvg:SvgCachedImage
Source="resource://yieldroadsign.svg" />
</StackLayout>
</ScrollView>
</ContentPage>
using System; using Xamarin.Forms;namespace _SVG_XFImage_vs_FFImageLoading
{
public partial class ImagesPage : ContentPage
{
public ImagesPage()
{
InitializeComponent();
} public void SetMeasuredTime(TimeSpan measuredTime)
{
measuredTimeLabel.Text = $"Measured time is {(int)measuredTime.TotalMilliseconds}ms";
}
}
}

Step 2. Adding an ImagePage iOS renderer

Now let’s create a custom renderer for the ImagesPage. The overall rendering time will be measured between render creation and a ViewDidAppear call. To achieve that I write a timestamp to the _startTime field and override ViewDidAppear method. Do not forget to register the renderer properly using the ExportRenderer attribute. After the ViewDidAppear method has been overridden it’s time to calculate the time and show it on the display using the SetMeasuredTime method from the previous step.

using System;
using _2_SVG_XFImage_vs_FFImageLoading.iOS.Renderers;
using _SVG_XFImage_vs_FFImageLoading;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;[assembly: ExportRenderer(typeof(ImagesPage), typeof(ImagesPageRenderer))]
namespace _2_SVG_XFImage_vs_FFImageLoading.iOS.Renderers
{
public class ImagesPageRenderer : PageRenderer
{
private ImagesPage _imagesPage;
private TimeSpan _startTime;
public ImagesPageRenderer() : base()
{
_startTime = DateTime.Now.TimeOfDay;
}

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement is ImagesPage imagesPage)
{
_imagesPage = imagesPage;
}
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
_imagesPage.SetMeasuredTime(DateTime.Now.TimeOfDay - _startTime);
}
}
}

Step 3. Adding an ImagePage Android renderer

Now let’s create a custom renderer for the ImagesPage. The overall rendering time will be measured between render creation and a ViewDidAppear call. To achieve that I write a timestamp to the _startTime field and override ViewDidAppear method. Do not forget to register the renderer properly using the ExportRenderer attribute. After the ViewDidAppear method has been overridden it’s time to calculate the time and show it on the display using the SetMeasuredTime method from the previous step.

using System;
using _2_SVG_XFImage_vs_FFImageLoading.iOS.Renderers;
using _SVG_XFImage_vs_FFImageLoading;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;[assembly: ExportRenderer(typeof(ImagesPage), typeof(ImagesPageRenderer))]namespace _2_SVG_XFImage_vs_FFImageLoading.iOS.Renderers
{
public class ImagesPageRenderer : PageRenderer
{
private ImagesPage _imagesPage;
private TimeSpan _startTime; public ImagesPageRenderer() : base()
{
_startTime = DateTime.Now.TimeOfDay;
} protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e); if (e.NewElement is ImagesPage imagesPage)
{
_imagesPage = imagesPage;
}
} public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated); _imagesPage.SetMeasuredTime(DateTime.Now.TimeOfDay - _startTime);
}
}
}

Step 3. Adding an ImagePage Android renderer

The general idea of the android renderer is the same: measure the time between render creation and some native API call that is called right after a page has been rendered. However, Android has no special native callback or event indicating that a view did fully appear. After some googling, I found a recommendation to use OnGlobalLayoutListener for that purpose.

using System;
using _2_SVG_XFImage_vs_FFImageLoading.Droid.Renderers;
using _SVG_XFImage_vs_FFImageLoading;
using Android.Content;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.Views.ViewTreeObserver;[assembly: ExportRenderer(typeof(ImagesPage), typeof(ImagesPageRenderer))]
namespace _2_SVG_XFImage_vs_FFImageLoading.Droid.Renderers
{
public class ImagesPageRenderer : PageRenderer, IOnGlobalLayoutListener
{
private ImagesPage _imagesPage;
private TimeSpan _startTime; public ImagesPageRenderer(Context context) : base(context)
{
_startTime = DateTime.Now.TimeOfDay;
} protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e); if (e.NewElement is ImagesPage imagesPage)
{
_imagesPage = imagesPage;
ViewTreeObserver.AddOnGlobalLayoutListener(this);
}
} public void OnGlobalLayout()
{
ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
_imagesPage.SetMeasuredTime(DateTime.Now.TimeOfDay - _startTime);
}
}
}

Measurement for the FFImageLoading way

Create a “Resource” folder inside of the shared project and add the SVG images to that folder. Don’t forget to set the “EmbeddedResource” value for the “Build action” property of every image resource.

15 images are in the Resources folder
Set EmbeddedResource build action and Resource ID

Everything is ready for launch. The results I got are on the following screenshots.

FFImageLoading measurement results. iPhone SE2020 (Left), Samsung A5 2017 (Right)

Measurement for the Xamarin built-in way
Step 1. Adding SVG images to iOS project

Although SVG images are supported by iOS since iOS 13, both the Rider IDE and the Visual Studio IDE still don’t allow adding SVG images for some reason.
However, there is a workaround covered by my previous article. Read it to learn how to add an SVG image asset to iOS project.

SVG iOS Assets

Step 2. Adding Android vector images

The native way to display SVG images on the Android platform is to convert an SVG image to Android VectorDrawable XML. Fortunately, it’s really easy to make this convertation. I usually use https://svg2vector.com. So after the convertation I add XMLs to Resources/drawable folder of the Android project. Remember: a name of an image must be the same for both iOS asset and Android drawable.

Android drawables

Step 3. Modifying the Forms project

Since we don’t need SvgCachedImage control anymore and to make the experiment more clear, I remove FFImageLoading.Svg.Forms NuGet from the project.

Uninstalling FFImageLoading NuGet

Now I need to modify the ImagesPage.xaml as it is shown below.

<ContentPage
x:Class="_SVG_XFImage_vs_FFImageLoading.ImagesPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Image">
<Setter Property="Aspect" Value="AspectFit" />
</Style>
</ResourceDictionary>
</ContentPage.Resources> <ScrollView>
<StackLayout Spacing="10">
<Label
x:Name="measuredTimeLabel"
FontSize="Large"
HorizontalOptions="Center" />
<Image Source="arrowuparrowdownsign" />
<Image Source="bicyclesroadsign" />
<Image Source="crossingsign" />
<Image Source="dangerousbend" />
<Image Source="horsesroadsign" />
<Image Source="nobicycles" />
<Image Source="noentry" />
<Image Source="payloadsign" />
<Image Source="roadlayoutsign" />
<Image Source="roadsignslippery" />
<Image Source="tramroadsign" />
<Image Source="trucksign" />
<Image Source="tunnelroadsign" />
<Image Source="warningsign" />
<Image Source="yieldroadsign" />
</StackLayout>
</ScrollView>
</ContentPage>

Step 4. Measurement

Now we a ready to launch the application again and see the results. Side note: I removed a previous version of the application from devices and called “Build->Clean All” for the entire solution.

Results:

Xamarin.Forms.Image measurement results. iPhone SE2020 (Left), Samsung A5 2017 (Right)

Conclusion

Comparison result

As you can see in the case of the iPhone there is almost no difference. However, Xamarin.Forms.Image control approach is more than twice faster when it comes to Android vector drawable images. When I compared those two approaches previously on other devices the result was the same: there was no significant difference on iPhone 8 but Xamarin.Forms.Image approach was twice faster on Google Pixel 5.

So as you can see although FFImageLoading.Svg.Forms is a great and easy-to-use plugin, when performance matters probably it’s better to not use it for embedded vector graphics.

Thank you and have a great day 🙂

Tools to convert SVG to VactorDrawable XML

Android Studio Guide — https://developer.android.com/studio/write/vector-asset-studio#svg
https://svg2vector.com
https://inloop.github.io/svg2android/


Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Aleksei Starkov


Print Share Comment Cite Upload Translate Updates
APA

Aleksei Starkov | Sciencx (2022-03-22T01:19:51+00:00) Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image. Retrieved from https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/

MLA
" » Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image." Aleksei Starkov | Sciencx - Tuesday March 22, 2022, https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/
HARVARD
Aleksei Starkov | Sciencx Tuesday March 22, 2022 » Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image., viewed ,<https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/>
VANCOUVER
Aleksei Starkov | Sciencx - » Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/
CHICAGO
" » Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image." Aleksei Starkov | Sciencx - Accessed . https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/
IEEE
" » Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image." Aleksei Starkov | Sciencx [Online]. Available: https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/. [Accessed: ]
rf:citation
» Performance: FFImageLoading.SVG.Forms vs Xamarin.Forms.Image | Aleksei Starkov | Sciencx | https://www.scien.cx/2022/03/22/performance-ffimageloading-svg-forms-vs-xamarin-forms-image/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.