Cross-Platform Mobile App Development with
Flutter – Xamarin – React Native:
A Performance Focused Comparison

Cross-Platform Mobile App Development with Flutter – Xamarin – React Native: A Performance Focused Comparison

Last Thursday I had the privilege to give a talk at Capital One’s iOS Summit in McLean, VA. This was the third time I was attending the conference and the second time that I got the opportunity to go on the stage. The venue was an impressive auditorium, the organization was impeccable, and the audience was energetic and cheerful. I got to attend a number of interesting talks, meet and exchange ideas with passionate software engineers who traveled from all over the country.

I don’t have a video of the talk but I will share a summary and as well as the slide deck. Here we go.

Mobile application development has grown beyond our wildest dreams. There are an estimated 2 billion smartphones in the world and more than 99% of them run either iOS or Android. In order to reach more users, developers need to target both of these platforms. Doing that is unfortunately far from being easy for a number of reasons.

Developers have to learn two languages (on iOS it used to be Objective-C but now Swift; on Android Kotlin is gaining momentum over Java) and two platforms. More often than not, there needs to be two platform teams as well. This approach is slow and expensive. It is difficult to align the iOS and Android feature release timelines. At a minimum, the App Store review process makes it more challenging for timely iOS releases. It is hard to deliver a delightful experience on any one platform and even harder to repeat that twice. Worse yet, if and when supporting the web becomes a requirement (unfortunately at times as an afterthought), the difficulty increases exponentially.

Previously, we have seen cross-platform solutions but they either compromised on performance or reaching design expectations. Google, Facebook, and Microsoft have been hard at work and I think they now have solutions that are worth taking another look. I want to explore three such popular frameworks: Flutter, Xamarin, and React Native, explain what they are, how they work, and compare them against each other with a focus on performance. My hope is that after reading this article, you are inspired to go check them out and know enough to formulate in your mind which technology could be the right choice for your needs.

Let’s start out with Flutter. It is an open source mobile app SDK that was developed by Google. It gives developers an easy and productive way to build and deploy beautiful and performant mobile apps on both Android and iOS. What makes it unique is that it neither uses web views nor iOS/Android UI components but still draws everything natively using its own rendering engine.

Instead of reinventing the wheel, the Flutter team looked extensively at the projects inside Google and reused as much of the existing code as it made sense. They took relevant pieces from Chrome, WebKit, Android and built a slim C++ engine. They chose to build the rest of the framework using Dart. The framework implements animation, painting, gestures, rendering, and provides an implementation of Material Design components as well as a sparse iOS-themed component library.

Flutter system architecture diagram. For further details please check out the original document.

On iOS, the C++ engine is compiled with LLVM and the Dart code is AOT (Ahead-Of-Time) compiled into native code. On Android, the C++ engine is compiled with the Android NDK (Native Development Kit) and the Dart code runs on the Dart VM (Virtual Machine) which generates JIT (Just-In-Time) compiled optimized native code. A system implementing JIT compilation continuously analyzes the code being executed, identifies parts where there would be a speedup, and translates those pieces of code to the device’s CPU instruction set. The translated code is called native code and it gets executed directly on the CPU as opposed to being run on the VM.

Flutter’s platform-specific API support does not rely on code generation but rather on a flexible message passing system. The Flutter portion of the app, the client, sends messages to the iOS or Android portion of the app, the host, over a platform channel. The host listens on the platform channel and receives these message. It then calls into any number of platform-specific APIs using the native programming language and sends back responses to the client.

Please refer to the slide deck for the performance discussions about the memory, CPU, and GPU utilization of a typical Flutter app.

Interestingly, I identified a memory leak issue while running these tests. I haven’t had a chance to file a bug with Flutter yet but I will do so in the next few days.

Let’s move on to the next framework on our list, Xamarin. Xamarin is an open sourced technology developed by Microsoft for using C# to build iOS, Android, and Windows Phone 8 apps. In contrast to Flutter, Xamarin gives access to the native iOS and Android UI components. What’s unique about it is that Microsoft offers a comprehensive set of services called the Mobile Center. Xamarin apps can be built, distributed, and monitored here. Push notifications can be sent through the Mobile Center. They even offer real device UI testing as part of a paid service called the Xamarin Test Cloud.

Xamarin apps are developed using Visual Studio. Visual Studio has mirrored a lot of the Xcode Interface Builder features. One can build complete UIs and navigation patterns without launching Xcode once. You can’t profile your code unless you purchase a hefty Enterprise subscription, though, and I found that disappointing since profiling was the most important thing I wanted to do. Fortunately, Instruments is able to attach any process and I was able to collect the metrics I needed. 

Xamarin iOS apps run with the Mono Runtime and the C# code is AOT compiled into native code. The Mono Runtime runs side-by-side with the Objective-C runtime and exposes access to the iOS APIs through bindings. On Android, the C# code and the bindings are complied and linked into an APK file which is executed via JIT on ART (Android Runtime). ART and Mono communication happens through JNI (Java Native Interface). JNI is a mechanism that enables Java code running in a JVM (Java Virtual Machine) to call and be called by native applications. In this context, ART can invoke methods on Mono via the ACW (Android Callable Wrappers) bridge and Mono can invoke Android code via MCW (Managed Callable Wrappers) bridge.

The way Xamarin has gone about supporting native UI components is good but comes with a tradeoff. When there’s a new iOS or Android version, Xamarin will not have full support immediately. There is a historical trend of quickly updating the iOS SDK sooner than the Android SDK. I have not been able to locate a formal definitive process about the turnaround time of such releases.

Please refer to the slide deck for the performance discussions about the memory, CPU, and GPU utilization of a typical Xamarin app.

Let’s switch gears a little bit and talk about React Native. React Native is built on React, which is Facebook’s JavaScript library for building web interfaces. React has been popular because it offers impressive performance especially for quickly changing data. 

React components describe their appearance by embedding HTML inside JavaScript and the framework handles the rendering. Similarly, React Native components describe their appearance by embedding XAML (Extensible Application Markup Language) and the framework handles the rendering by mapping these components to their native iOS or Android counterparts. The XAML tag ”<Text>”, for example, maps to UILabel on iOS and TextView on Android.

At the core of React Native is a bridge that lets native code to call JavaScript and vice versa. Events at the native layer are packaged into function ids, arguments using a custom JSON-based protocol, serialized, and passed over to the JavaScript layer through the C++ bridge. The JavaScript layer processes these events by calling a number of native functions. The results of all such functions are batched together, serialized, and sent back to the native layer asynchronously over the C++ bridge. The native layer than deserializes and processes the responses and updates the UI accordingly.

There are a couple more popular frameworks that are worth mentioning but for which we don’t have time to deep-dive. One of my favorites is AngularJS Material which is both a UI component framework and a reference implementation of the Material Design specification. The rightmost app in the first demo was built using AngularJS Material and it looks and feels native but in a very Android look and feel. Another one of my favorites is Ionic, which is a framework built on Angular and provides both iOS and Android themed UI components. Ionic apps can be deployed on iOS and Android devices using Apache Cordova. NativeScript is a framework that’s architected much like React Native and allows developing cross-platform apps using Angular, TypeScript or JavaScript.

Please refer to the slide deck for the performance discussions about the memory, CPU, and GPU utilization of a typical React Native app.

I also thought it would be relevant to look at some computer language benchmarks for Dart, C#, and JavaScript. 

In general it may be a bit meaningless to ask which language is faster as the efficiency of the code one writes determines how fast it will run. However, I think it is a good practice to be aware of the possible performance implications of bytecode running on a VM vs machine code directly executed on the CPU. Please refer to the slide deck for details.

At the end of the talk, I compared the three frameworks side-by-side according to 6 criteria: Performance (CPU, GPU, memory utilization, binary size), portability, developer experience, production readiness, user experience, and longevity. While some of these are objective criteria, my conclusion is that there isn’t a one-size-fits-all solution. Every product has a different context and every organization has a different set of challenges. The key is to ask the right questions, arm yourself with knowledge, and make a decision based on evidence. 

I hope you now have a better idea about these technologies and I was able to pique your interest to go and check out these frameworks!

For a complete list of references, please refer to the slide deck.

Update 10/13/2017: I just got to filing a bug about the memory leak in the Flutter demo app. You can check out the details here: Memory leak scrolling the List demo in Flutter Gallery iOS app.

Update 11/30/2017: Flutter engineering team is investigating this issue and they have commented the following:

“Memory usage continues to increase because we hold images in the ImageCacheand do not evict items from the cache until it exceeds a maximum size (which defaults to 1000). The app can set imageCache.maximumSize to limit cache size (at the expense of repeatedly retrieving and decoding images).

Images are cached at full size, not the size they are rendered at if the app scales them down. Also, replacing the image widgets and doing a GC will not affect image memory consumption because the image cache remains populated.”

I have asked if this could be avoided by ignoring duplicate images (assuming determining duplication is non-trivial) and I’m waiting for a response.

Update 1/2/2018: The leak issue was resolved and closed. Another similar issue, Display same jpg, flutter need six times memory size bigger than iOS Native was closed in relation to this leak

Update 5/21/2018: A coworker pointed out to me that the Visual Studio Magazine quoted me in their article "Xamarin Faces Challenge from Google's Flutter Mobile SDK". I'm flattered!

Umer Qaiser

"Learn, Un-learn, Re-learn." | ●7.5+ Years in Tech | ●Product Development, Project Management, Software Engineering | ●Areas: SaaS, App/Web, AI/ML, RPA, IoT, Astronomy | ●Stacks: DotNet/.NET, React/Vue, C#/JS/TS/Python

3 年

Valuable knowledge! Thanks. Korhan Bircan I have a question: Why did Microsoft use React Native instead of Xamarin to build their Fluent UI framework? I'm just confused about it, I guess.

回复
Giorgos Papadakis

Flutter Mobile Developer at LearnWorlds

7 年

Fluent is great for copy pasting a sample and run it (i did it also) but just consider going to for a large app without relying on separation design between UI and Bussiness layer. The franework doesnt provide such a thing as Xamarin with MVVM Prism MVVMCross which forces developer to write clean and maintainable code

回复
John Lawson

Senior Engineering Manager at Quizlet

7 年

Excellent summary! Did you get a chance to file that bug yet? I'll check out flutter soon!

Michael Jones

VP of Engineering at Trust & Will

7 年

Missed the event, but thrilled you'll post the video. Great post, Korhan!

要查看或添加评论,请登录

Korhan Bircan的更多文章

  • My Most Important Career Lesson: The Power of Networks

    My Most Important Career Lesson: The Power of Networks

    As I reflect on my professional journey, one lesson stands out above all others. The most valuable asset in any career…

    10 条评论
  • Unpacking Square's Developer Productivity Approach

    Unpacking Square's Developer Productivity Approach

    Excited to share the first part of my multi-part blog series about the evolution of Developer Productivity at Square!…

    4 条评论
  • Influencing Through Trust and Agreement

    Influencing Through Trust and Agreement

    In this final segment of our discussion about influence, we're looking at how to communicate effectively, especially…

    1 条评论
  • Influencing Through Creating Win-Win Situations

    Influencing Through Creating Win-Win Situations

    Welcome back! In the first installment of this blog series, we laid the foundation by focusing on relationship…

  • Influencing Through Relationship Management

    Influencing Through Relationship Management

    Welcome to the first installment of a three-part blog series where we'll dig into the complex world of influencing…

    2 条评论
  • Scripting Your Career’s Narrative: A 5-Point Story Arc Approach

    Scripting Your Career’s Narrative: A 5-Point Story Arc Approach

    Recently, I had the privilege of delivering an engaging keynote address at a Developer Productivity offsite event…

  • Highlights from GitHub Universe2020

    Highlights from GitHub Universe2020

    GitHub Universe took place between 12/8-10 this year and for the first time, it was streamed for free to the public. I…

    5 条评论
  • Dev Tools & Ops @Scale

    Dev Tools & Ops @Scale

    Five years ago I attended the first @Scale Conference at Facebook's Menlo Park Campus and it instantly became one of my…

    1 条评论
  • Integrating Cross-Platform Frameworks

    Integrating Cross-Platform Frameworks

    Cross-platform mobile frameworks have gained popularity for good reasons. They match the native look&feel and…

  • C1 Mobile Summit

    C1 Mobile Summit

    Capital One's San Francisco Mobile teams are on a roll and I'm delighted to see the positive reception to the annual…

社区洞察

其他会员也浏览了