Today’s topic is Code Quality & Performance with Xamarin / Xamarin.Forms.
When we talk about code quality and performance we talk about the user’s experience. When our application is poor in performance can cause slow interactions with the users, our app can be freeze sometimes, our app can reduce battery life or the device can get hot just because of an operation in a loop that’s never ended.
However, when we talk about quality and performance there is more than just implementing efficient code. We can improve our application performance in many ways. There are many techniques, tons of articles, and some really nice conferences talking about this topic.
What I have here is a recompilation of all of them with some best practices, tools, techniques, and so on. I’m telling you, this article is going to blow your mind if you work with Xamarin.
What is Xamarin?
If your new in this world, just let’s start talking about what is XAMARIN. Xamarin is an open-source platform for building modern and performant applications for iOS, Android, and Windows with .NET. Xamarin is an abstraction layer that manages the communication of shared code with underlying platform code.
When we talk about Xamarin we have two approaches that we can follow. One of them is Xamarin Traditional (Or Xamarin Classic as some people call it).
Anything you can do in Objective-C, Swift, or Java can be done in C# with Xamarin using Visual Studio, Visual Studio for Mac, and Visual Studio Code in near future with MAUI.
On the other hand Xamarin.Forms is a UI framework that allows developers to build Xamarin.iOS, Xamarin.Android, and Windows applications from a single shared codebase.
Brand new app?
The first thing is making good architecture choices.
- So pick a good MVVM framework like Prism, ReactiveUI, MvvmLight, or just what you like.
- If there are going to be databases involved, make sure you’re picking a good repository pattern.
If you’re new in the Xamarin Forms world or you have a small project Xamarin.Forms Shell can be a good option because you will have probably all the tools you need to work with.
Pick your dependencies wisely. So don’t go too dependency-heavy. Try to make your app light and snappy. So pick those wisely, and of course test often.
Already have an app?
The architecture that you have is the best choice? If it’s not I wrote an ebook with 7 Tactics to structure your Projects with Xamarin.Forms that you can use today for both new projects and projects already created.
You can download here.
In the official Microsoft Xamarin Documentation, there is a section focus on improving Xamarin.Forms app performance.
Here some recommendation:
- Enable the XAML compiler*, Use compiled bindings*, Use fast renderers*. These options are enabled by default but for older solutions, you need to enable them manually.
- Reduce unnecessary bindings: Don’t use bindings for content that can easily be set statically. (For example the name of the page)
- Choose the correct layout: For example, if you have a stack layout, that is capable of having multiples children, with a single child is wasteful.
- Optimize layout performance, Use asynchronous programming and Choose a dependency injection container carefully are specific tips that I recommend you to follow in the guide.
- Use CollectionView instead of ListView: CollectionView is more flexible, and performant than ListView.
- If you are using ListView be sure to Optimize performance with Initialization, Scrolling, and Interaction.
- Reduce the visual tree size: Reducing the number of elements on a page will make the page render faster.
- Reduce the application resource dictionary size: XAML that’s specific to a page shouldn’t be included in the application’s resource dictionary, because the resources will be parsed at application startup instead of when is required by a page.
You can follow the complete guide here.
Creating apps with Xamarin.Forms
I wrote an article talking about Examples, and tips for creating applications in Xamarin Forms
In this article, I talk about The three pillars to develop better applications that are:
- Your app
- The purpose of your app and
- The developer
Also, I gave you some general tips and tips for increasing your application’s performance. In the performance section, I gave you some resources you can check.
An important tip:
Try to avoid RelativeLayout and AbsoluteLayout as much as you can.
Also in the same article, I gave some tips for Visual Studio and some tips to help you choose the best MVVM framework.
In the same way, you have their tips for your XAML and C# projects and much more.
You can read the complete article here.
I know this is list is small but if you think about it I promise you, you will see the results immediately.
- Don’t start/register all services right in the beginning, lazyload where possible.
- Don’t download all your data on startup.
- Lazy Load Anything You Don’t Need Immediately.
- Think about User Experience.
- Enable layout compression
- Enable startup tracing on Android
- Use AOT with startup tracing for faster startup.
- You can use custom profiles with startup tracing.
- Linker settings
- Turn on Link SDK Assemblies Only when your app is in Release [at the very least]
- Turn on Link All/SDK and User Assembles when your app is in Release [test manually]
- Enable [assembly:LinkerSafe] in binding projects
- Use Android App Bundles.
Here some resources:
- Optimize Xamarin.Android builds. link
- Xamarin Android App Bundles. link
- Xamarin Show – Android App Bundles. link
- David Ortinau’s Blog Post to boot Xamarin.Forms startup time. link
- Using Custom AOT Profiles with Xamarin.Android. link
- Faster Startup Times with Startup Tracing on Android. link
- Faster Application Startup using Custom Profiles with Startup Tracing. link
- Investing Time in the Xamarin Linker for Smaller App Sizes. link
- Optimizing Xamarin Apps & Libraries with the Linker. link
- Linking on Xamarin.Android. link
- Xamarin.Android Linker Tricks Part 1. link
- Enable LLVM optimizing compiler
Here some resources:
- Linking on Xamarin.iOS. link
I know these things are something you’d hear again and again but trust me, it’s very important to remember these rules.
- Always detach Event Handlers and Dispose Observers
- Unsubscribe from events and avoid anonymous delegates to prevent memory leaks
- A reference to the anonymous method can be stored in a field and used to unsubscribe from the event
Just remember to unsubscribe from events and remember to unsubscribe them before the subscriber object is disposed of. That’s it, keep that in mind at the beginning.
Later then read the post I’ll give you and apply some other best practices.
In .NET, any normal reference to another object is a strong reference. That is, when you declare a variable of a type that’s not a primitive/value type, you are declaring a strong reference.
For example, here object A and object B have strong references to each other, and because of this, this creates what we call an immortal object.
Immortal objects are circular strong references. On Xamarin.Android the GC handles that but in Xamarin.iOS we need to be careful.
But hey we can Use a weak references to prevent immortal objects.
A weak reference is created using the instance of the object being trapped. So object A maintains a strong reference to object B, but object B maintains a weak reference to Object A.
Load Data Efficiently
When your loading a page you need to think about user experience. You need to be informative when you’re loading your views and their data.
A good practice is to load the local content first, I’m talking about your views and components that you have locally, and in the background then you can start loading your data.
You need to provide to users an experience of like, there’s something happening and not just like there is nothing appearing on the screen.
You can use a placeholder like labels, images, loading icons, activity indicators, etc. Something that I like is defining states like (busy, complete, canceled, etc..) and you can use that with some extra animations.
Don’t bind things that can be set statically: if you have two labels, for example, one does describe something and the other one is what actually gets updated with some sort of data, don’t bind the descriptive label to the ViewModel, things like these will improve your app performance.
Aqui algunos recursos:
- Xamarin.Forms Memory Performance Best Practices. link
- Alexyey Strakh’s Xamarin Show Episodes: Memory Management. link
- Stop Weak reference: Xamarin Community Toolkit: WeakEventManager. link
Async/Await and Task best practices
I also wrote a post talking about this topic here.
Async/Await is one of those topics that you feel like you know a lot about but then you don’t. The reality is there are a lot of different ways to use Async/Await, and that’s part of the problem.
So, in the article, I give you some tips like how to invoke tasks, how to await multiple tasks, and what you need to know about threads.
For Tasks you have tips like how to return Tasks, avoid “using void” methods in order to know the state of your process, how to return Task inside try/catch or using block, and so on.
Also, you have some tips for Xamarin.Forms and some Plugins and extensions that you can use.
I really recommend you to read the post here.
Error handlers and Task wrappers
I wrote an article about Global errors handling in Xamarin Forms
Many times we may encounter unhandled exceptions that are very difficult to detect and log, and you must do so in order to handle errors in your application.
There are global handlers on each platform to allow you to receive notifications of exceptions that you haven’t handled elsewhere. That’s a really nice post I recommend.
When we work with Task and Command most of the time we do common implementations of scenarios where we use repetitive code. For example use IsBusy, try-catch, Loggin, etc.
The idea is to make a wrapper that allows us to store all this logic for us to reuse that code.
I have some really nice tips that you can check over there.
Validate User’s Entries
There is a library that is included in all my Xamarin projects and that is Plugin.ValidationRules.
Improve the quality of your data using validation rules. Validation rules verify that the data the user enters into the record meets the standards you specify before the user can save the record.
A validation rule can contain a formula or expression that evaluates the data in one or more fields and returns a value “True” or “False”. Validation rules also include an error message to display to the user when the rule returns a value “False” due to an invalid value.
Simple but powerful
You can see the new version here.
Best practices for managing yours resources
- Icons, Images, Assets
- Using unoptimized asset for each platform and form factor ü
- Faster image loading
- Putting large files in .NET Standard project
- Defer key/fundamental images or resources by loading from the web
- Consider using:
- Implement caching with FFImageLoading for frequently used images
Here some resources:
- Jonathon Pepper’s Blog Post on GlideX for Android. link
- Android Asset Studio. link
- Xamarin.Android Alternate Resources. link
- Xamarin.Forms Nuke. link
- FFImageLoading for Xamarin.Forms. link
- mFractor plugin for Visual Studio. link
- Shared Images for Xamarin with Resizetizer NT. link
Dependencies best practices
- Optimize dependencies being used
Remove everything not being used (extra nugets and dependencies). Make it nice and clean. So be smart about it, cut down and just use as many as necessary.
- Set your NuGet Package Manager options to use PackageReference as the default
Migrate package.config to PackageReference. Start moving over the Package Reference and in Visual Studio and under NuGet Manager you can actually set your default preference on new projects now, which is great and awesome.
Here some resources:
When you want to get all sort of useful data from your app is when you need to use profiler.
Profiler helps you…
Look for memory leaks, large images, large object graphs, wide scopes, cross-references, contexts that prevent the garbage collector from working property, etc…
Measure: Startup time, Operation time, Memory consumption, CPU profile, Networking profile, I/O profile, Etc…
You have some profiler options that you have out there in case no one knows, we have Xamarin profiler, Xcode instruments, and Android Studio profiler.
And in case you’re wondering, how to start to use these tools, here you have all resources you need.
Visual studio extensions
XamRight – Visual Studio Marketplace: Xamright helps you streamlines your Xamarin forms development and reduces your debugging cycle.
XAML Styler – Visual Studio Marketplace: XAML Styler is a visual studio extension that formats XAML source code based on a set of styling rules. •
Async Method Name Fixer – Visual Studio Marketplace: The easiest way to analyze and fix method names for asynchronous methods.
This is all that I have in this article for you. I know it’s going to be useful for you.