FlutterでUIを構築する際に個人的に気をつけていること

2023/12/10に公開

この記事は何?

この記事は、FlutterでモバイルアプリケーションのUIを構築する際に、個人的に気をつけていることについてその理由と例を提示しながら説明を行う記事です。

この記事が対象としている読者

  • Flutterを使い始めてまだ日が浅い開発者
  • 他人はどういった点に注意しているのかが気になる開発者

結論

私がFlutterでモバイルアプリケーションのUIを構築する際には、 コーディング効率とメンテナンス性パフォーマンスと最適化テスト容易性 の3点を気をつけています。

  • コーディング効率とメンテナンス性
    • 目的にあった適切なWidgetを使用する
    • 宣言的な組み方をする
  • パフォーマンスと最適化
    • なるべくconstコンストラクタが使えるような組み方をする
    • 画面に表示されるまで描画を遅延させるような組み方をする
  • テスト容易性
    • Widgetテストが書きやすくなるような組み方をする

コーディング効率とメンテナンス性

目的にあった適切なWidgetを使用する

気をつけている理由

「車輪の再発明」を避けるため

構築したいUIを実現できるWidgetがFlutter公式で存在していることに気づかず、「車輪の再発明」をしてしまうのは、コーディングの効率が悪いと考えています。

そのWidgetを選択した意図を分かりやすくするため

HTMLを書く際になんでもかんでもdivを使わないのと同様に、FlutterでUIを構築する際にも適切なWidgetを選択することで後から見た際にこのUIで何をしたかったのかを伝えやすくなると思います。

以下のようなUIを構築する際に、どうやって実装するかを考えてみてほしい。
一般的にこういったUIは「GridView」で実装するだろうが、もし「GridView」の存在を知らなかったら、「LayoutBuilderとWrapの組み合わせ」のような「車輪の再発明」めいた実装を選択してしまうかもしれない。

https://github.com/TowaYamashita/flutter2023_advent_calendar/blob/main/lib/page/layout1/layout1_page.dart

気をつけなくてもよい場合の条件

単純なUI構築で、パフォーマンスやメンテナンス性に特別な考慮が必要ない場合。

補足

「車輪の再発明」を避けるための情報収集の手段として、以下の2つを使うとよいと思います。

宣言的な組み方をする

気をつけている理由

Flutterの思想に合わせるため

Flutterは宣言的UIフレームワークです。
宣言的UIはUIの構造を直感的に理解しやすく、コードを見るだけでUIのレイアウトと機能が明確になる利点があります。
したがって、なるべくコードはFlutterの思想に沿ったコードの書き方に合わせることでわかりやすさと統一感が生まれコーディングの効率がよくなるはずであるため宣言的な書き方にすることが重要だと考えています。

https://github.com/TowaYamashita/flutter2023_advent_calendar/blob/main/lib/page/layout2/layout2_page.dart

気をつけなくてもよい場合の条件

命令的に書けばスッキリ書けるのに無理に宣言的にして読みにくくしてしまうのは本末転倒なので、そういった場合は命令的に書いても良いと思います。

パフォーマンスと最適化

なるべくconstコンストラクタが使えるような組み方をする

気をつけている理由

buildの度に再生成させるのではなく使い回させるようにするため

constキーワードを使用すると、Widgetがコンパイル時に定数として扱われるようになり、アプリケーション内で使い回されるようになる。それによってアプリケーションの起動時間の短縮やランタイムパフォーマンスの向上が期待できます。

気をつけなくてもよい場合の条件

動的に変更される要素が多く、constコンストラクタを使うことが難しい場合は無理しなくて良いと思います。

補足

Flutter公式が提供しているパフォーマンスベストプラクティスにおけるconstコンストラクタの使用を推奨する記述
https://docs.flutter.dev/perf/best-practices#control-build-cost

画面に表示されるまで描画を遅延させるような組み方をする

気をつけている理由

リソースの使用を最適化するため

ListView.builderなどを使用することで、画面に表示されている部分のみを描画し、リソースの使用を最適化します。
特にリストやグリッドなど、多くの要素を持つUIでは、画面に表示される部分だけを描画することがパフォーマンスに影響します。

https://github.com/TowaYamashita/flutter2023_advent_calendar/blob/main/lib/page/layout4/layout4_page.dart

気をつけなくてもよい場合の条件

小規模なリストやリスト内のアイテムを生成するコストが高くない場合は、遅延ローディングさせなくてもよいと思います。

補足

Flutter公式が提供しているパフォーマンスベストプラクティスにおける遅延読み込みに関する記述
https://docs.flutter.dev/perf/best-practices#implement-grids-and-lists-thoughtfully

テスト容易性

Widgetテストが書きやすくなるような組み方をする

気をつけている理由

Widgetテストをガードレールのように扱えるようにするため

コードを改修したりリファクタリングする際に余計な部分を壊していないかの確認やこのWidgetはこういった状況のときにどういった振る舞いをするのが正しいのかの確認がしやすい状態だと嬉しいです。
その状態にするには、なるべく多くパターンを網羅しているようなWidgetテストを整備する必要があるため、Widgetテストが書きやすいような構成になっていることが重要だと考えています。

https://github.com/TowaYamashita/flutter2023_advent_calendar/tree/main/lib/page/layout5
https://github.com/TowaYamashita/flutter2023_advent_calendar/tree/main/test/page/layout5

気をつけなくてもよい場合の条件

非常に単純なUIでわざわざテストを書くまでもない場合、またはWidgetテスト以外の手段でテストを実施している場合は考慮しなくても良いと思います。

Discussion