Curiosity killed the Flutter

Overview

In this post I'd like to give you a high level overview of the Flutter framework; I try to explain what Flutter is and isn't, how it works, and instead I deliberately ignore how to start to code with it, as there's plenty of material online. Stay with me if it sounds interesting to you.

What Flutter is

Flutter is a cross-platform framework (developed by Google), based on the Dart programming language (developed by Google). Flutter allows developers to deploy a mobile application on both Android and iOS; the very same application, actually.
Last but not least, Flutter is the primary way to write an application for Fuchsia, a new os (developed by Google).
At the time of writing, September 2019:

Name Stable Initial Stars Open issues Commits Contributors Forks
Flutter 1.9.1 05.2017 75269 7888 15773 446 9282
Dart 2.5.0 10.2011 4267 4895 66676 233 552

Note that Flutter can also deploy the application as web application and as desktop application; these features are still experimental and partially immature, and I will cover them both in following posts.

Cross-platform look and feel

When I deploy an application on both Android and iOS using Flutter, the application looks and interacts exactly the same on both platforms, though adapted, and it feels natural on each platform:



Flutter accomplishes this by respecting the differences between the Android and iOS platforms; for instance the navigation transitions and animations, the scrolling, icons, fonts, text editing, keyboard, basically all the interactions with the platform are respected and adapted.
As Flutter is a mean to design beautiful widgets, it comes with an exhaustive and pixel perfect catalog of ready made widgets, that the developer can compose on UI. In particular the Material widgets are designed according to the Material Design guidelines, and the Cupertino widgets are designed according to the iOS design language.
As an example, adaptation happens for icons: if the Material package is used, some icons, like the menu icon or the home icon, show differently on each platform:




Another example is about fonts: if the Material package is used, then each text will default to Roboto on Android and to the San Francisco font on iOS. If instead the Cupertino package is used, then each text will always use the San Francisco font on both the platforms.
This guarantees that the interactions with the platform are respected, while at the same time the interaction within the app looks and feels the same on both the platforms.

How it works


Flutter claims to build high-performance apps. Let's see how is that possible, given the difficulty to deploy on both the platforms. The framework is written in C, C++, Dart and the Skia Graphics Engine, and it contains:

  • Modern react-style framework
  • 2D rendering engine (Skia)
  • Ready made widgets (Material and Cupertino)
  • Development tools
The framework is modern, and built with reactiveness at its core; the rendering engine Skia is heavily optimized for mobile 2D rendering, with text and shadows at ease; the widgets are pixel perfect and extensive; and last but not least the development tools are great, well documented, and with an amazing community.





When I write an application, I code in Dart composing widgets with the Flutter framework. When I deploy the application on Android, both my Dart app code and the Flutter SDK Dart code are compiled into the apk as native libraries (ARM and x86) into a runner Android project; but the Skia engine C/C++ code is compiled into the apk too. So when the app is launched, the Flutter library is run, and it handles all the rendering, inputs and events, delegating them respectively to the Skia engine, and to the Flutter and app libraries (the former for platform interactions, the latter for in-app interactions). A very similar approach is used when the app is deployed on iOS.
The approach is the same used by games which run on both the platforms, using a game engine which renders the UI.
So Flutter's beautiful and pixel perfect widgets are rendered by the Skia engine on UI. Which implies that on both the platforms Flutter doesn't use the native system's OEM widgets. So, literally, Flutter is not native. But it feels completely native, mocking it to the pixel. And relying on its own super optimized rendering engine and set of widgets, so that it paints on an empty canvas on both the platforms, which eases the maintainability. Another implication of not relying on the system's widgets is that the widget I choose will look the very same throughout all the os versions.
With this approach, Flutter can easily reach a good performance of constant 60 fps, and even 120 fps when possible.

Conclusion

I've to confess I've always been skeptical about cross-platform technologies before (for instance React Native), but the peculiar angle taken by Flutter made me feel curious enough to try it immediately, especially because of been Google's. So as a skeptical and curious Android developer, I really fell for Flutter, because despite the cross-platform part, I can see in it all the lessons learned from 10 years of Android development. So many good patterns, good habits, and architectural structures in Flutter are built-in, instead of recommended or enforced. If you're a developer and you've reached this far, my 2 cents: give it a try, because it's free and it takes literally 2 minutes to start to experiment with it, and with Dart you'll feel at home as it's like a Java++.

Comments