Is Flutter ready for production apps in Q4 2018?

No Comments

I first tested Flutter back in February, while it was still in alpha. Although it showed promise, there were a lot of problems. At the time of writing, Flutter is approaching its 1.0 release.

What follows is a brief overview of my experience using Flutter for the past few weeks. My task was to build a relatively simple prototype for iOS and Android.

Hot reload is great

Hot reload allows you to instantly see changes, without needing to redeploy or rebuild your app. Just save and changes are “instantly” shown on the device or simulator/emulator. Once I got used to this feature, I found that I really miss it while working in environments that don’t support it. Hot reload really sped up my workflow, but it would stop working once in a while and I would have to rebuild the project. This happened mostly while editing localizations (more on this later).

Note: Some of the other cross-platform frameworks (such as React Native) also support hot reload.

Setup is reasonable

If you already have an Android or iOS development environment set up on your machine, adding Flutter is pretty straightforward. In my case, I just needed to install Flutter and Android SDK, since my machine was already set up for iOS development.

A couple of IDEs support Flutter. If you are so inclined, you can even use a plain text editor and deploy from the terminal. I decided to use Visual Studio Code with the Flutter and Dart plugins, and I’ve been pretty happy with it.

If you get stuck at any point flutter doctor is a great feature which tells you exactly what needs to be installed.

Localization is cumbersome

If your app is going to be used in multiple languages, prepare yourself for some head scratching. The process is not straightforward, which is reflected in the tutorials.

Compared to native localization, it seems unnecessarily complicated. I won’t try to summarize the process as it would require a post of its own. I will say that you don’t have to use the suggest intl framework and .arb files (which need to be converted multiple times). Instead, you can roll you own solution with JSON or maps/dictionaries.

Embedding native components is hard

It is pretty simple to show a native overlay over a Flutter app. It is relatively straightforward to embed a Flutter app in a native app. Embedding a native view in a Flutter app is a wholly different level.

The project I was working on required a barcode scanner. This was pretty simple to add using the built-in package manager. Unfortunately, after testing the app, the client decided that the barcode scanner needs to be embedded instead of an overlay. After finding another barcode scanner library, I was sorely disappointed by the performance. 100% CPU usage on an iPhone X and a lot of dropped frames in the preview.

To see if the performance issue could be solved, I did quite a bit research on how to display native components such as the camera feed, maps and others. At the moment there seem to be two options, AndroidView which is expensive in terms of performance and unfortunately lacks an iOS counterpart, and the Texture component.

Using the Texture component and a native barcode scanner plugin, I managed to get a working solution that had a 20-25% CPU utilization on the same device. Although this was quite an improvement, it took a long time to achieve and unfortunately solved only half the problem since the same still needed to be done on Android. Since I have no Android experience, I had to rely on my colleagues for help.

To get an idea of the complexity of a Flutter plugin which embeds a native view (that doesn’t even handle touch events), you can take a look at Flutter’s own camera plugin.

Syntax takes a while to get used to

This part is highly personal, but it took me a while until I felt comfortable with the syntax. The “widgetised” nature of Flutter often results in “pyramids of doom”, which might put off some people.

Widget build(BuildContext context) {
  return Container(
    child: Center(
      child: Text(
        'Hello world',
        style: TextStyle(
          color: Colors.white,
          fontSize: 20.0
        ), // TextStyle
      ), // Text
    ), // Center
  ); // Container
}
Example: a simple centered label. It can get ridiculous pretty fast.

This can be solved in a few ways, but it doesn’t help that the documentation and most tutorials don’t put much effort into alleviating this issue.

Since VS Code uses the standard Dart formatter, at the moment it is not possible to change the indentation spacing. So I was stuck with the unusual 2-space indentation.

Smaller than usual indentation, autogenerated closing comments and seemingly randomly optional semicolons/commas can make it feel pretty cluttered. Sometimes I would just rewrite the whole build function instead of hunting for the missing parenthesis, bracket, semicolon or comma.

Rough edges are visible

At the time of writing, Flutter has around 4.000 open issues. I’m not saying this to put down Flutter contributors. They are doing a great job having closed over 9.000 issues. However it does give you an idea of what you are getting yourself into.

One example of issues you might run into is the ExpansionTile class. At first, I was pleasantly surprised by how easy it is to make expandable sections. I soon realized it is not possible to programmatically collapse or expand a section. This is a problem in and of itself, but it is exacerbated by a related issue. Two adjacent expanded tiles have a double separator between them.

Apart from minor issues like the ones mentioned above, I had bigger problems. The debugger would randomly disconnect or the app would crash for no apparent reason. This might be due to my setup or the plugins I’m using. It impacted my development nonetheless, and there was no actionable way for me to react except frustration.

Summary

Since the last time I had a chance to use Flutter, it has come a long way, but there are still problems. At this stage, Flutter seems to be a great tool for building prototypes or perhaps MVPs, depending on the complexity.

If you are targeting a single platform, it is probably easier to go fully native. You’ll have to write some native code either way.

If you are a developer with no mobile development experience or have worked with only one platform, Flutter is a good place to start for simple CRUD apps. Just be prepared to spend some time fixing things.

I’m still not completely sold on Flutter. I will definitely keep an eye on it and test it more extensively if the opportunity presents itself.

Nikola Lajic

Part of the codecentric Novi Sad team since 2013, working with mobile apps since 2009. Nikola has worked on all sorts of mobile projects, from quizzes to enterprise applications. He is interested not only in developing apps but also in how users experience them.

Comment

Your email address will not be published. Required fields are marked *