I’m Shuyu Guo, the author of “Detailed Description of Flutter Development”. I’m responsible for Github GSY series of open source projects, such as GSY_Github_app_FLUTTER and GSYVideoPlayer.

See this topic you should know that today’s topic is not pure technical content to share, can be said to be a little thankless, in fact, I rarely share this kind of topic, but recently feel it is necessary to do such a popular science content.

The status quo of Flutter

I came into contact with Flutter around 2017. It is interesting to say that at that time, I needed to do an internal sharing about cross-platform technology, the main purpose of which was to promote the React Native framework to other divisions of the company. I happened to see Flutter at that time. I added it to my share as a placeholder, and from then on I began my story with Flutter.

Back to the subject, Flutter has been open source for almost seven years now, and as of 2022, Flutter is no longer the niche cross-platform framework it once was.

As shown in the figure, by the time I took a screenshot in February, it can be seen that Flutter now has a star of up to 137K. 10K + Open and 50K + Closed issues are sufficient to indicate the activeness of Flutter community and users.

According to official data, Flutter has surpassed all other cross-platform frameworks to become the most popular mobile cross-platform development tool, with nearly half a million applications using Flutter as of February 2022.

As you can see from this chart, Flutter was also the number one “used” and “loved” cross-platform framework in the second half of last year. We can see that Flutter increased significantly between 2019 and 2022, with nearly 42% of cross-platform developers using Flutter.

In fact, last year and the year before, I did some simple statistics:

  • In 2020,52It’s in one sample19Flutter appeared in one App;
  • In 2021,46It’s in one sample24Flutter appeared in one App;

Based on February 22, 2022, the data obtained after comparing 57 commonly used apps are as follows:

Flutter React Native Weex Not using cross-platform
27 24 5 13
Chain home, around, gold digging,Chinese University MOOCs, Flush, Ele. me, Phoenix News, wechat, Wechat, Bilibili Comics, Tencent Classroom, enterprise wechat, Learning power, Idle fish, Ctrip, Tencent Conference,weibo, Shell House, Baidu Web disk, WPS Office, ViPSHOP,Meituan crowdsourcing,Meituan Takeaway business edition,UC, QQ (Libmxflutter),Millet movement,Youku video Meituan,Meituan crowdsourcingMeituan Takeaway business edition, Meituan Takeout, IQiyi,Chinese University MOOCs, Maimai, Xiaohongshu, Anjuke, Dewu, 58.com, Wechat Reading, Autohome, Feishu, Ximalaya, Where to Travel, Ctrip, Jingdong, Kuaishou, Ctrip,M home,UC,Millet movement,Youku video UCIdle fishweiboMi Jia, Youku video QQ Music, Boss direct pin, today’s toutiao, fluent say, Zhihu, Tencent news, Finance and Economics, cool dog music, Pin-duo duo, Douyin, starting point, what is worth buying, Baidu Map

These data are derived from Android Apk and are based on the existence of dynamic libraries such as libflutter. So, libreactnativejni.so and libweexcore.

It can be seen that Flutter and React Native are both close to 50%, while Weex’s share is already very low. In addition, based on this small sample, it can be seen that most apps are more or less likely to have some cross-platform framework.

At the same time, the App in bold uses more than one cross-platform framework, such as UC and Xianyu, for business needs.

According to the official Q4 survey last year, 72% and 91% of Flutter developers developed apps for iOS and Android, respectively, in the past six months.

Dart’s third party plug-in hosting platform pub.dev, based on 2022-02-22:

All 23495 packages
Flutter 21714 packages
Android/iOS 20352 packages
Web 12584 packages
PC 14314 packages
Null safety 12615 packages

There are currently approximately 23,000 publicly available third-party support packages hosted on Pub, of which 21,000 support Flutter. As you can see, Dart language users are mostly from Flutter.

In addition, according to the data, most libraries support Android and iOS, and the support for Web and PC is close to 60%. Surprisingly, the current support for Null Safety is close to 60%, which means that more than 40% of the packages are still on the older version.

According to the official Q4 survey, the proportion of Flutter used as the main work is gradually increasing.

Finally, a word about Flutter. The official idea about Flutter has always been:

No matter how good an SDK is, if only a few people are using it, it’s not valuable. An SDK, even if mediocre but used by a large number of developers, will have a healthy and thriving ecosystem where the people who use the framework can benefit from it.

By the way, do you know what people dislike most about Flutter in the survey?

It’s text editing! In the Q4 survey, satisfaction with the text editing feature dropped from 82.3% (single line) and 82.2% (filtering and formatting) to 69.6% (multi-line) and 66.6% (rich text editor). Currently, the multi-editing experience and input rich text support are not particularly friendly.

Flutter VS Other

Having talked about the current state of Flutter, let’s move on to some intuitive comparisons between Flutter and other frameworks.

Realize the principle of

In fact, this part of the content has been shared many times, briefly, first compare their implementation principle, as shown in the figure below, it can be seen:

  • In the case of native Android or Compose, the native code is rendered by SKia to GPU. The Android native system comes with SKia.

  • For Flutter, the Dart code controls pass through the SKIA to be rendered on a GPU. The SkIA used on Android and the SKIA packaged into the project are used on iOS.

  • For ReactNative/Weex and similar projects, they are running in their respective JS engines, and finally through mapping to native controls, using native rendering capabilities for rendering;

  • For Hybird’s cross-platform frameworks such as Uni-App, the main use is WebView rendering capabilities; (WeeX is not discussed)

Flutter is theoretically the closest implementation to native because the implementation path is basically the same, RN/Weex is relatively poor, and UNI-app rendering via WebView is the last.

However, in many cases, the performance threshold lies not in the framework, but in the developer. I have seen the performance and experience of apps developed with Cordova very well. I remember talking to the head of Alipay at a conference, and Alipay also uses a lot of H5 Hybird technology. Thanks to UC’s own kernel, the performance experience has been quite good.

Building size

Then we compare the size of app builds, mainly on Android, because the size of apps on iOS seems to be getting less and less noticed. Take QQ as an extreme example:

Back to the question of app size, I happened to see some people say earlier:

“Compose generates JAR/AAR files for JVMS and Android via Kotlin/Native, framework files for IOS via Kotlin/JS, and Web files for Kotlin/JS “JavaScript files, which end up calling native apis, make the adoption of Compose Multiplatform not a performance drain or a significant application size increase like Flutter.”

Yes, the implementation of Flutter should take up more volume than Compose, but what is the real situation?

First we create a few empty projects, and then we package them with only arm64-V8A-related dynamic libraries, because usually only one of the SO libraries is stored in the shelf.

We built the Android Release package without writing any code and got the following results:

  • Flutter

  • React Native

  • Compose

  • Native Android

You can see:

  • React Native has the largest empty package. The bulk of the empty package comes from its internal dynamic libraries, such as JSCore.
  • The main volume of Flutter comes from its internal dynamic libraries, such as the framework of Flutter.
  • Compose is fairly similar in size to native, with the bulk of its content coming from classes files; Of course, there’s no obfuscation and compression, which can be much smaller;

The result shows that the Flutter does occupy a larger volume than Compose, but there is one thing to note here:

  • With Flutter development alone, the main application volume will come fromlibapp.so, this part of the code is the Native binary code after AOT compilation;
  • For Compose, the bulk of the increase comes from the classes file, which needs to be compressed by obfuscating, etc.

As an added bonus, you might be wondering, how does Compose compile its layout?

For a quick note, the Compose control is not the same architecture as the native control. If you look at the compiled content, you will see that a control like BOX is laid out and drawn by ComposerKt, BoxKt and other framework implementations.

Therefore, Compose does not compile into a native Android View to display, but relies on the Canvas of the platform. In this respect, it is similar to Flutter. Simply put, Compose is a completely new set of Views.

Note: Compose’s component can display layout boundaries on Android, even though it’s a new View.

As for volume, I happen to open source a number of GSY projects that implement very similar business logic, so after packaging them in Release mode, we compare their size:

  • Flutter

  • React Native

  • Native Android

Because I don’t currently have Compose’s project, here’s a comparison of the original, as you can see:

  • The Flutter project changed from empty 5.7m to 9.8m, increasing its size by 4.1m;
  • React Native project changed from 9.4m to 12.7m, an increase of 3.4m;
  • Native project changed from 3.2m to 9.3m, increasing the size by 6.1m;

Although imprecise, it can be seen that the total size of Flutter and native projects does not differ much in roughly the same business scenario, while native projects actually increase more significantly than Flutter.

However, the premise here is that native compression and obfuscations are not enabled. If compression and obfuscations are enabled, as shown in the figure below, the volume changes from 9.3m to 6.4m. Therefore, it can be seen that after obfuscations and obfuscations are enabled, the volume of native App does not differ much from that of Flutter.

In addition, I have tested a pure Compose online, and found that the size of the Compose component changed significantly from 9.6m to 2.4m after the componding and componding function was enabled. This is due to the fact that most of the code in Compose can be obfuscated.

Therefore, the conclusion is drawn:

  • Compose, with compression enabled, is actually smaller and has an advantage over Flutter because of the compression efficiency of classes
  • React Native is generally larger than a Flutter, as is Weex;

Of course, this is not absolute. The size of Flutter sometimes depends on the habit of developers. For example, ONE day I happened to see in the group that the business dynamic library of Flutter of an App can be as high as 77.4m.

What is this concept? Generally, 10m-15m is the size of the Flutter dynamic library of ordinary small and medium-sized apps, while large apps are generally controlled between 20m-35m, even if their sizes are very large. For example, THE size of THE Flutter dynamic library of UC is 35M and that of enterprise wechat is 28.9m.

Therefore, the size is more subjective control of the developer, and also depends on whether you turn on obfuscation and compression. This is mainly introduced to let everyone have a visual understanding of the packaging products of different projects, so as to provide a judgment on which development framework to choose.

The build process

Let’s talk about the build process, and why we’re talking about this, because the problem with the build process is that it’s easy for a novice to give up.

The following figure illustrates the common problems encountered by non-native developers running Flutter:

If you see that you are stuck in assembleDebug, then Android is actually downloading some environment dependencies, such as Gradle SDK, AAR libraries, etc., from the network. This process cannot be seen by flutter run or idea. You can only see similar progress by entering andorid/ and executing./gradlew assembleDebug:

For example, according to a survey of Flutter official Q4, the need to deal with Xcode (iOS) and Gradle (Android) is the most common problem when releasing apps. Why this? First of all, unfamiliarity with native platforms can be a pain point for cross-platform development.

Of course, the React Native node_module black hole has always been a headache for both Weex and React Native, although the Flutter is not the best of all cross-platform developments:

For example, the React Native project’s node_module black hole often causes it to surprise you when you install and run the environment. A variety of plugins and tools are both useful and bloated at the same time. For example, I encountered this problem when I had to deal with a React Native project for a long time ago:

Depending on the dependencies, each library version requires a different Node environment, and I need to balance it out. Of course, this is not the most troublesome thing. The most troublesome thing is that after the successful operation of COMPUTER A, the problem is found to be unable to run after the NPM of COMPUTER B. I believe this is A required course for every React Native development.

From the perspective of front-end development, such as flat dependency, of course, after the expansion of flat dependency depth will become a considerable number of files and directories, dependency structure becomes not intuitive, of course, now NPM, PNPM tools have new optimization,

On the contrary, Flutter is much lighter in this respect. Dart’s pub package level is very shallow and its path is relatively clear, which is why I think Flutter is basically more comfortable than React Native in this respect. Therefore, under the same dependency complexity of the Native environment, Flutter is indeed easier to enter the Hello world than RN.

Flutter & Compose

Finally, the comparison between Flutter and Compose.

I believe that you have seen the comparison between Flutter and React Native a lot. Because React Native has been released for a long time, and different companies maintain Flutter and React Native. For Flutter and Compose, they are both open source projects from Google and support multiple platforms. What is the difference between them? How to choose?

First, as an aside: There is NPM on the front, Pub on Flutter and cocoaPods on iOS. You can search their websites for libraries you want, check their popularity, version, compatibility and usage, etc. But what about Android?

Android Gradle does not have such a convenient existence that we can only search for it on Github by keyword. In fact, this effect also permeates into Compose, which is a problem for Compose’s cross-platform development.

First, Google officially defines Compose as a modern native interface toolkit for Android, and as we explained earlier, it’s a brand new UI, so Compose has its own platform, Android, which is its home.

As you can see from the official roadmap, Google’s experience with Compose is mostly focused on the Android native platform, while the Compose Multiplatform is implemented by the Comement-JB maintained by JetBrains.

Flutter has no platform of its own. It is a UI framework that spans multiple platforms. Flutter was born for multiple platforms, and is currently supported on Android, iOS, The Web and Windows.

So here’s one of the biggest immediate differences: Compose is Google’s new UI framework for Android, and JetBrains has expanded it to support cross-platform, which is what Flutter was designed for.

Although both are cross-platform, there are significant differences between them, as shown in the figure below:

The difference in implementation is that Flutter supports multiple platforms through an official Framework, while Swarm currently supports multiple platforms through multiple module implementations.

Not to mention, Flutter generates code for different platforms through different commands at compile time. This includes the unified Flutter framework to complete the output. Currently, the implementation logic of Compose on the Web, Desktop and Mobile is not necessarily universal. Especially the Web.

Compose is currently not officially supported on iOS, and although it can be supported in a few ways, it is not particularly convenient. On the Web, the packages that Compose needs to use and import are specialized. Instead, Mobile and Desktop share the content of compose- UI.

For example, the support code for the Web in composing – JB is shown below, and you can see that both the imported and used controls have their own particularities.

import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.css.*

fun main(a) {
    var count: Int by mutableStateOf(0)

    renderComposable(rootElementId = "root") {
        Div({ style { padding(25.px) } }) {
            Button(attrs = {
                onClick { count -= 1 }
            }) {
                Text("-")
            }

            Span({ style { padding(15.px) } }) {
                Text("$count")
            }

            Button(attrs = {
                onClick { count += 1 }
            }) {
                Text("+")}}}}Copy the code

So for Compose, it’s more like: You learn the framework, and then you have the ability to write Web and Desktop; For Flutter, the cross-platform experience is even better.

So from my understanding:

  • Compose is the new Jetpack UI library for Android UI development, which is meant to redefine the way UI is written on Android, so you can develop Android UI with or without it. But if you continue to dig deep into Android, you’d better learn.
  • The future of Flutter is multi-platform, a more stable and reliable multi-platform UI framework. If you’re not going to be a big front-end or multi-end developer, it doesn’t matter if you can’t.

From this point of view, whether you learn to Compose or Flutter first, it will help you to master the other skill, which is equivalent to learning 70% of the other one:

  • If you are a native developer and have not yet been exposed to Flutter, learn Swarm first, which will be more helpful for your Android career, and then learn Flutter.
  • If you are already using or learning about Flutter, please continue your education and do not have to worry about Compose. You will not be too far away from Flutter once you master Flutter.

Comparing many of the design concepts and source code of Flutter and Conpose, their implementations are quite similar.

Of course, the reason why cross-platform is cross-platform is that there are corresponding native platforms in the first place. Many problems of native platforms need to be solved by returning to the platform. Those who like to boast about the rhythm of XXX dominating native platforms are just because “your anxiety will become their profit”.

Some opinions

Finally, a brief comment on some of my insights.

The underlying logic of cross-platform

Before Flutter, the underlying logic of mobile cross-platform was of two kinds:

  • One is to use WebView cross-platform;
  • One is to rely on proxy native control cross-platform;

Therefore, the early cross-platform controls on mobile end started with frameworks such as Cordova and Ionic. The purpose of these frameworks was to extend the capabilities of front-end H5 to the App side, so that the front-end development capabilities can be easily developed for Android and iOS applications. I remember the slogan at that time was: Write Once, run Everywhere.

Later, thanks to the popularity of React, React Native opened up a new logic: Write the native App in the way of front-end. By converting JS controls into native controls for rendering, the cross-platform performance of mobile terminal is freed from the limitation of WebView and the performance is improved. React Native emphasizes learn once and write everywhere. In other words, you can develop web pages and apps as well.

With Flutter, it does not rely on platform controls. It produces a set of platform-independent controls that can be rendered directly on a GPU. This is undoubtedly the highest cost, but the resulting “decoupling” and “WYSIWYG” is the best. The slogan of Flutter is Build apps for any screen.

However, if Flutter is applied to real application scenarios, it does not mean that Flutter is the optimal solution, but you need to weigh your business scenarios to choose the appropriate framework for you. For example:

  • If your business scenario is a hybrid development of multiple frameworks, Flutter will not have an obvious advantage.
  • If your scene requires strong text editing and rich text scenes, Flutter will have no advantage.
  • If your KPI is particularly sensitive to memory usage, Flutter is not particularly advantageous either;
  • If you need a thermal update, Flutter doesn’t have an advantage either;

Hot update

Now that we’re talking about hot updates, let’s talk a little bit about hot updates. First of all, Flutter does not officially support thermal updates. Unlike React Native, Flutter has a mature and universal code-push framework.

Why is that? First of all, JS code written by React Native is pure script text. Even if it is packaged as a bundle file, it is still in plain text format. Therefore, it is not illegal to send a bundle through code-push. Also code-push can’t deliver packaged native platform code because it’s not compliant.

The AOT code packaged with Flutter is an executable binary. If you deliver it directly using hot update logic, it would violate Apple’s App Store and Google Play policies.

The answer is yes, due to the “necessity” of hot update in China, there are also many third-party frameworks, such as:

MxFlutter, Fair, liteApp, Flap, Flutter_code_push, etc.

None of these are directly delivered compiled binaries, for example:

  • MxFlutter uses JS/TS write controls to deliver updates;
  • LiteApp is entered through the Vue template;
  • Flap is used to process THE DSL and coding process of Dart.

All of these practices require some sacrifice for thermal updates, so that Flutter is inherently “unfriendly” to thermal updates.

Of course, if you don’t have Google Play, the Android Hot Update So Dynamic library is not a barrier to entry, so if you can actually use the existing plug-in solution rudely on Android.

Multiple platforms

Finally, a few words about the multiple platforms of Flutter. Remember Build apps for any screen? Isn’t Flutter also write Once, run everywhere? Android, iOS, Web, Windows, MacOS, Linux, etc.

Based on my experience, I would say write Once, Run everywhere are nice but unrealistic. Flutter does allow one set of code to run directly on all platforms, but in the current experience, the cost of one set of code for all platforms far outweighs the convenience it provides.

Start with Web. The Web platform is the most special among the several platforms, because it needs to adapt the operation logic of Mobile and PC. Currently, Flutter Web:

  • It is used on MobileHtmlCanvas, which is converted to the Web side of the “native” control for rendering, which brings the difficulty of coupling and API adaptation;
  • Flutter can be used on PCCanvasKitTo draw, but it useswasmTechnology is currently relatively “radical”, the actual volume, SEO, compatibility are problems;

So Flutter Web isn’t working yet, so what’s the point of releasing a stable version of Flutter Web? Because your code supports packaging into the Web!

When you build an App for Android and iOS, you can quickly build some of the UI and business of the App into a Web page, and that’s the value of it so you don’t have to start from scratch to implement the rest of it, as long as it’s “not unusable.”

Currently, Flutter Web is used for projects such as Ali Seller, Meituan Takeaway business Classroom, etc

Speaking of PC, the application logic of PC itself is very different from that of mobile phones: Mouse, keyboard, adjustable window size, horizontal screen, scroll and other aspects are actually difficult to be directly compatible with a set of code. In my understanding, it is more about some controls, animation, UI, list, business logic, etc. on Android and iOS, which can be directly used on PC when needed. If you really need better experience, I suggest at least separate PC and Mobile from two business projects.

So if you really want a set of code, is there any good support? There is responsive_framework, for example.