Xamarin Forms FastRenderers for Android

Included from 2.3.5, FastRenderers are several new renderers for Android, that speed up the rendering of certain elements. There are currently 4 FastRenderers in 2.3.5. These include ButtonRenderer, FrameRenderer, LabelRenderer and ImageRenderer. They are enabled by default, however the old renderers still exist, to ensure backwards compatibility. This has now changed for 2.4.0, and you need to enable FastRenderers with this flag, that you do just before your Xamarin.Forms.Init line, in the OnCreate of your MainActivity.cs.


What Changed?

You could group these changes into two sections. I will go through the major change first.

Removal of ViewRenderer

The most noticeable change, is the removal of each renderer, inheriting from ViewRenderer<TView, TNativeView>. Before you would see the ButtonRenderer do this.

ButtonRenderer -> ViewRenderer<Button, AppCompatButton>
                      -> Control

Now it will inherit directly from the native Xamarin Android control, in Android.Support.V7.Widget.

ButtonRenderer -> AppCompatButton

It still implements IVisualElementRenderer, hence overrides such as OnElementChanged and OnElementPropertyChanged are available.

Where do the Speed Improvements come in?

The speed improvements are obtained, via a reduced layout cycle. In the existing ViewRenderer, a layout change would involve this.

OnLayout(ButtonRenderer.cs) -> OnLayout(ViewRenderer.cs) -> OnLayout (VisualElementRenderer.cs)
                                   -> MeasureAndLayout           -> ForChildren -> Renderer.UpdateLayout()

In the fast renderers, the layout cycle is reduced.

OnLayout(ButtonRenderer.cs) -> OnLayout(AView)

Batch Updates

Moving to the VisualElementTracker, which all renderers use, old and new, a change was made to batch updates. Previously all layout parameters were set one by one e.g. X/Y Anchor, rotation, opacity, scale and translation. Now, all of these properties are sent at once, for more efficient processing by Android, with FormsViewGroup.SendViewBatchUpdate.

Performance Improvements

The performance improvements, will vary for each application, depending upon the complexity of your layout. Based off other developer’s experience, some have seen a x2 improvement, others have only seen a few percentage point speed improvement. The use case that will most likely see the greatest improvements, is a large ListView and very fast scrolling. Flat or simple layouts, will unlikely see any noticeable improvements to your end users.

There will no doubt be more FastRenderers coming in the future, which will hopefully improve the speed of your application further, with no additional work.


  1. Andrew

    I wish someone measured the performance gain for each element which got the ‘new’ renderer (I’m refraining myself for calling it ‘fast renderer’ 🙂 )

    1. Adam Pedley

      The XF team have measured the performance. They have Performance measuring code scattered throughout the renderer. Besides their response of up to 2 times faster, they haven’t released any specific numbers on specific hardware.

    1. Adam Pedley

      Yes, but you will need to create your own CustomButtonRenderer, then inherit from the old ButtonRenderer. Its just the ButtonRenderer that isn’t under the namespace FastRenderers.

      Then have this renderer used for ALL buttons.

      [assembly: ExportRenderer(typeof(Button), typeof(OldButtonRenderer))]
      namespace MobileApp
      public class OldButtonRenderer: Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer

  2. NMackay

    I’ve been using 2.3.5-pre6 for a large scale LOB app development, it’s generally been very stable, there are small pitfalls with label height calculation in scrollviews in tabbed pages but overall the fast renderers have been stable (label issue was fixed by wrapping in a stacklayout).

    1. Adam Pedley

      Thanks for letting us know. I suspected that many edge case issues might surface, which is why I was slightly surprised they did it as default initially. Good call on their part to change it to optional. They can put it as default in a few versions, once it has been thoroughly tested, in some production apps.