導入
roadmap.shのFlutterの2本目の記事になります。
Widget周りはまぁ理解しているつもりになっていますが、特に公式のサイトを読んで理解したというよりは、利用していく中で理解したことが多いので、今回もroadmap.shに従ってWidgetのStatelessWidgetについて勉強しましたのでそのまとめです。
元々のサイトはこちら。
StatelessWidget
概要
StatelessWidgetとは、、、変更可能な状態を必要としないウィジェットです。
言わずもがな、ですが。
StatelessWidgetは、オブジェクト自体の設定情報やウィジェットが展開される BuildContext 以外のものに依存しないUIにおいて便利です。状態に依存して動的に変わる可能性のある構成については、StatefulWidget の使用を検討する必要があります。
パフォーマンスの考慮事項
StatelessWidget の build メソッドが呼び出されるのは、以下3パターンある。
- ウィジェットがツリーに最初に挿入されたとき
- ウィジェットの親が設定を変更したとき (Element.rebuild を参照)
- ウィジェットが依存している InheritedWidget が変更されたときです。
2点目のように定期的に親ウィジェットが設定を変更する場合、または3点目のように頻繁に変更される InheritedWidget に依存している場合は、ビルドメソッドのパフォーマンスを最適化して、スムーズなレンダリングパフォーマンスを維持することが重要です。
StatelessWidget の再ビルドの影響を最小限に抑えるテクニック
- ビルドメソッドによって生成されるノードの数を最小限に抑える
- 例
- 複雑な
Rows
、Columns
、Paddings
、SizedBoxes
の配置を使用する代わりに、単にAlign
やCustomSingleChildLayout
を使用することを検討する。 - 複数の
Containers
とDecorations
を使用する代わりに、単一のCustomPaint
ウィジェットを検討する。
- 複雑な
- 例
-
const
ウィジェットを使用する。 - StatelessWidget を StatefulWidget に変更して、StatefulWidget の例にあるような技術を使用できるようにします。
- 例
- サブツリーの共通部分のキャッシュ
- ツリー構造を変更する際に GlobalKeys を使用する
- 例
- InheritedWidgets を使用してウィジェットが頻繁に再ビルドされる可能性がある場合には、StatelessWidget を複数のウィジェットにリファクタリングし、ツリーの変更がある部分をリーフに押し込む。
- 例
- 4 つのウィジェットで構成されたツリーについて、最も内側のウィジェットが Theme に依存している場合、そのウィジェットを構築するビルド関数の部分を独自のウィジェットに切り出すことを検討する。
- これにより、テーマが変更されたときに最も内側のウィジェットのみを再ビルドするだけで済む。
- 4 つのウィジェットで構成されたツリーについて、最も内側のウィジェットが Theme に依存している場合、そのウィジェットを構築するビルド関数の部分を独自のウィジェットに切り出すことを検討する。
- 例
- 再利用可能な UI 部品には、ヘルパーメソッドよりもウィジェットを使用する。
- 例
- ウィジェット構築に使用する関数がある場合、
State.setState
の呼び出しは、返却されたラップウィジェット全体をFlutterが再ビルドする必要がある。- その代わりにウィジェットを使用すると、更新が必要な部分のみを効率的に再レンダリングできる。
- さらに、作成されたウィジェットが const であれば、よりパフォーマンス改善につながる
- ウィジェット構築に使用する関数がある場合、
- 例
StatelessWidgetの例
GreenFrog という StatelessWidget サブクラスのスケルトン
class GreenFrog extends StatelessWidget {
const GreenFrog({ super.key });
@override
Widget build(BuildContext context) {
return Container(color: const Color(0xFF2DBD3A));
}
}
色と子ウィジェットを指定できるより一般的なウィジェット Frog
class Frog extends StatelessWidget {
const Frog({
super.key,
this.color = const Color(0xFF2DBD3A),
this.child,
});
final Color color;
final Widget? child;
@override
Widget build(BuildContext context) {
return ColoredBox(color: color, child: child);
}
}
終わりに
今回StatelessWidgetについて、公式のサイトを読んでみました。
今回触れた技術や最適化の方法を活用し、FlutterアプリケーションのパフォーマンスとUXを向上させていきたいと思いました。Flutterのウィジェットシステムを深く理解し、最適な構成を模索していきたいです。