5 things I like about Flutter and 4 things that annoy me.

Jul 8, 2019(5 years ago)-
Fuxing's Picture
Fuxing Loh

Flutter IntelliJ IDE

Back in early 2018, I came across a video introducing Flutter as an alternative to React Native for building a cross-platform app. I was very excited back then as the idea of Google, the developer of Android introducing their cross-platform development framework was quite promising for its adoption.

I have experience developing in Native Swift & Java, and it’s 2019 now, I thought I draw some comparison and write down some of the features in Flutter that makes it more adoptable and pleasant to use.

1. Forcing you to choose Stateful & Stateless Widget

For short, reactive design is by far the best feature in Flutter. Pretty much every front-end development is all about manipulation of state and reflecting the state. Flutter UI components are called widgets, and you either implement a stateful or stateless widget. Widgets describe what their view should look like given their current configuration and state.

A stateless widget holds no state; it is what it is; it doesn’t react to changes on its own. A stateful widget has state information that describes how the widget should look. The widget itself has specific mutating properties that manipulate the state causing the widget to change its state, therefore, its appearance. Typically, a stateful widget is where you put your on click listener and API callback as they cause the state to change.

You could build an application without strictly following any design patterns, but having the reactive paradigm baked directly into the core of Flutter offers a refreshing approach. It creates the blueprint for implementation that makes it compulsory as you build your highly interactive and data-driven application without needing to pick a framework for it.

The unexpected outcome of this design is that it dramatically reduces code lookup time when I am trying to change something small; as stateless widget is often your styled component that describes how a widget looks. While your stateful widget often encompasses state changes, which are usually where features and functions of the application are.

2. Incorporated Design & AutoLayout

Flutter styling is incorporated directly into code. It’s very closely tied to your text or variable that you are styling. You don’t have to look beyond a few lines of code to find the line to manipulate the styling.

Flutter widget is also very modular. When you need a particular style or feature, you wrap it inside a widget providing that style or feature. When you need padding on each side, you wrap your widget inside a Padding widget. When you need a corner radius, you use a BoxDecoration with a BorderRadius property.

The modularity of Flutter widgets allows very high reuse of its UI component as they don’t belong to any implementation. You don’t have to worry about whether a widget can be used for list view or grid view (UICollectionViewCell and UITableViewCell) you can easily swap them out as they are non-exclusive.

The side effect of this modular design forces you to place your widget in a widget tree. I like working with this widget tree structure as widgets are tightly packed together and traversing up and down the widget tree describes the causality they have with each other. Imagine a bunch of <div> in HTML but instead of <div><div><div></div></div></div> its

<border radius={3}>
  <padding p={16}>
    <icon></icon>
  </padding>
</border>

The best part is that it isn’t a templating language. It’s in code.

ClipRRect(
  borderRadius: BorderRadius.circular(3),
  child: Padding(
    padding: EdgeInsets.all(16),
    child: Icon(
      url: "image.png"
    ),
  ),
)

When the tree gets too complicated, you can wrap it inside a newly created widget.

class ComplicatedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(3),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Icon(
          url: "image.png"
        ),
      ),
    ),
  }
}

When you need to use that widget tree structure, you can just ComplicatedWidget().

3. Dart Lang & Type Safety

As an application and a team grow, the more communication will be required in code; whether it’s in the form of API documentation or code comments/documentation. I feel type safety in a language often does best at communicating what a variable should hold and how a method should be used and what to expect.

Many advantages of a type-safe language do not just end with the obvious arguments that people usually make (type safety). I like working with an IDE (IntelliJ) when developing. Statically typed language does make it easier for the IDE to predict what to autocomplete, and the analysis tools are much better and faster.

I also like working with Dart lang. It is what you expect a modern language to be: concise, asynchronous, functional, class-based and streamable.

4. Performance

This is a little tricky; there is no way Flutter can be faster than its native counterpart. I think, most importantly, it is its perceived performance. When I presented a flutter application to my engineering friends, they didn’t notice it wasn’t a native app.

Performance is always important, but what I could gather is that the proper understanding of stateful & stateless design dramatically affects the performance of a Flutter application. If you are doing multiple state manipulation individually in each widget in a list view while scrolling, you are bound to notice the lag. Carefully designing your widget tree tends to negate the lag.

5. Open Source & Debugging

The reasons why I liked open-source frameworks is the ability to easily travel down the code stack trace and realize why an anomaly is happening. My frustration mainly comes from developing apps in iOS Swift; when an exception occurs, it usually doesn’t describe what is happening. Whether it is the way you use a method or the illegal variable you passed, having documentation closely tied into code tends to resolve the exception faster for me.

Flutter Shortcomings & Concerns

scroll-to-index-problem

There are, of course, a few shortcomings and concerns when adopting new technology. All of my shortcomings are situational to what and how I was building my app and should not reflect entirely on your Flutter adoption.

Lack of Engineering Talent

One of the problems with a new framework is the limited engineering talent pool you can hire; basically nobody.

If it’s a solo project and you are planning to build your app to cater to both Android & iOS (and hopefully Fuchsia soon) then it’s perfect, you can build it with Flutter and probably shave some time off.

However, if you already have a team or is planning to hire a team. Then it’s a little tricky as there isn’t any senior Flutter engineer floating around in the market.

Very limited SDK Support

Flutter is still very new and not widely adopted. Most apps today require many components from multiple platforms to work. You might be advertising on Facebook, and you want to utilize the Facebook conversion tracking, you went ahead and implemented the Facebook SDK then you realise it’s not fully supported on Flutter.

Your support team might want to use Intercom to support customer in-app. But Intercom SDK doesn’t have an SDK for Flutter. You pray to the open-source community that there is an open-source plugin written by a saint. You went ahead with the implementation, and it all works out well, but… a few months later it comes to haunt you as Intercom dropped support for the version you are using. You checked the public repo and realized the maintainer is now busy with another project and dropped support for that repo. You now have to clone and maintain the project just to implement the change.

Map View Support

Google Map support on flutter is limited at the time of writing. There is some small visible latency at initialization, you can only add markers, but you can’t customise the Marker. You can’t add polygon or lines.

You may opt to develop the map feature natively, but you end up having to maintain three codebases with their relevant engineering talent (iOS, Android, Flutter) which is not ideal.

Scroll To Index

Scroll to an index on a list view might sound trivial, but due to the nature of how Flutter renders the widget, you can’t determine the height until you scroll to the widget. If all your widget is of the same height, then you could multiply the index and the height to get to the scroll position.

However, if your items in the list view are dynamically generated, and you have no way to determine the height, then tough luck. Depending on your use-case, there are certainly ways to overcome it, but it won’t be obvious enough.

This feature might impact your decision for adoption, but I will gladly go ahead with this handicap as the layout system that Flutter uses is god-damn amazing.

Conclusion

The shortcomings & concerns were trivial for me as its design and benefit outclass the shortcomings by a million miles. I enjoyed using Flutter. I hope you consider trying it out for your next project.