Flutter で build メソッドをリファクタするとき Widget は class に分割するべし
この Youtube で述べられている内容だが、Flutter で build メソッドがでかくなってきて component に分割するか〜と思う時がある。
その時、 Helper Methods と呼ばれる方法と、 class で Widget を作る方法があるがパフォーマンスの観点から class Widget を利用した方がよい。
どう違うのか?
こういう Widget があったとする。ボタンをタップすると state が更新されるだけの Widget。
これを Helper Methods と class Widget の2つのパターンで確認してみる。
class WidgetSample extends StatefulWidget { const WidgetSample({Key? key}) : super(key: key); @override State<WidgetSample> createState() => WidgetSampleState(); } class WidgetSampleState extends State<WidgetSample> { var count = 0; @override Widget build(BuildContext context) { print('build'); return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('count $count'), ElevatedButton( onPressed: () { setState(() { count += 1; }); }, child: const Text('tap'), ), const Text('very heavy widget.'), ], ), ), ); } }
Helper Methods
Helper Methods と呼ばれるのは以下のようにメソッドとして widget を切り出す方法である。
@@ -90,12 +90,17 @@ class WidgetSampleState extends State<WidgetSample> { }, child: const Text('tap'), ), - const Text('very heavy widget.'), + _buildVeryHeavyWidget(), ], ), ), ); } + + Text _buildVeryHeavyWidget() { + print('very heavy widget.'); + return const Text('very heavy widget.'); + } }
このコードでボタンをタップすると、state が更新されるたびに print('very heavy widget.');
が呼ばれることを確認できる。
Class Widget
では次に class で Widget を作成し、 const で呼び出す。
}, child: const Text('tap'), ), - const Text('very heavy widget.'), + const _VeryHeavyWidget(), ], ), ), @@ -98,6 +98,18 @@ class WidgetSampleState extends State<WidgetSample> { } } +class _VeryHeavyWidget extends StatelessWidget { + const _VeryHeavyWidget({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + print('very heavy widget.'); + return const Text('very heavy widget.'); + } +}
このコードでボタンをタップすると、state が更新されても print('very heavy widget.');
は呼び出されない。
必要がなければ build method が呼ばれないようになっている。
おわり
簡単な画面構成だったら Helper Methods 方式でも大きな影響は出ないが、動画にも述べられているようにアニメーションが走る画面であったり、地図アプリでユーザがスクロールするたびに state が更新されるうような画面は class にしておかないとチラつきや遅延が目立ってしまうので普段から class で Widget を分割するように心がけておくと良い。