こんにちは。
今回はFlutterのパフォーマンス改善の中でも定数オブジェクトを生成する「const」に着目して調べたことをまとめたいと思います。実装をしていると「Use 'const' with the constructor to improve performance.
」と警告が出る場合がありますが、その内容についても触れていきます。
constとは
Flutterにおけるconstは、定数(constant)Widgetや不変のオブジェクトを表すために使用されます。Dartでは、constはコンパイル時に値が確定するオブジェクトの宣言に使われ、FlutterのWidgetツリーのパフォーマンスを最適化するために重要な役割を果たします。
constの役割とメリット
1. 定数インスタンスを生成
constを使うことで、不変のWidgetインスタンスが作られます。このインスタンスは一度生成されると再利用され、同じ内容で再生成する必要がなくなるため、レンダリング時のパフォーマンスが向上します。
2. 再レンダリングの回避
constで作られたWidgetは、Flutterの再ビルドの際に状態が変わらない限り再描画されません。これにより、Widgetツリー全体での再レンダリングを減らし、アプリの動作を効率的にします。
3. メモリ使用量の削減
同じconstインスタンスは再利用されるため、複数の箇所で同じWidgetや値を使う際にメモリの節約になります。
以下はドキュメントから引っ張ってきたコードですが、同じ内容を持つ2つの定数インスタンスを作成しようとした場合、Dartはそれらを1つの共有されたインスタンスとして扱っています。
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
assert(identical(a, b)); // They are the same instance!
一方で定数でないオブジェクトの場合は、異なるインスタンスとして扱われます。
var a = const ImmutablePoint(1, 1); // Creates a constant
var b = ImmutablePoint(1, 1); // Does NOT create a constant
assert(!identical(a, b)); // NOT the same instance!
constの使用が適切な場面
- StatelessWidgetで不変のプロパティを使う場合
- 再利用できるWidgetの場合(アイコンや静的なテキストなど)
- コンパイル時に確定する値(リスト、マップなど)を生成する場合
注意点
- 状態を持つWidgetや動的に変化する内容には使用できない
- パフォーマンス最適化のために、可能な限りconstを活用することが推奨されるが、むやみにconstを付けるのではなく、不変であることが確実な箇所にのみ付けるのが理想
Use ‘const’ with the constructor to improve performance.

flutter_lintを入れていると、constが必要な箇所にconstが書かれていない場合「Use 'const' with the constructor to improve performance.
Try adding the 'const' keyword to the constructor invocation.
」と警告が出されます。
この警告箇所にconstを記述することでこの警告は解除されます。
constの書き忘れを防ぎ、パフォーマス改善に繋げてくれるのでflutter_lintはONにしておくことをおすすめします。
flutter_lintはanalysis_options.yaml
で設定することができます。
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
補足
多数のconstがネスト構造的に使用されている場合、定数オブジェクト内ではconstは不要になります。(≒ constが自明である場合は省略できます。)
例えば以下のようなコードでは、定数オブジェクト内で多数のconstが使用されています。
// 多数の const が使用されている例
const pointAndLine = const {
'point': const [const ImmutablePoint(0, 0)],
'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};
これは以下のようにconstを省略して記載することができます。
// 最初の const だけで定数コンテキストを確立する例
const pointAndLine = {
'point': [ImmutablePoint(0, 0)],
'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
まとめ
- Flutterにおけるconstは、定数Widgetや不変のオブジェクトを表し、コンパイル時に値が確定するオブジェクトを生成する
- 不変のWidgetインスタンスを作成し、同じ内容で再生成を避けることでパフォーマンスが向上する
- const Widgetは再ビルド時も再描画されないため、アプリの効率が向上する
- constを定義することで同じインスタンスが再利用され、メモリの節約に役立つ
- flutter_lintを利用することで、constの不足を防ぎ、パフォーマンス改善に役立つ
- 定数オブジェクト内では、最初のconstだけで定数コンテキストが確立されるため、ネストされたconstを省略できる
参考
https://dart.dev/language/classes#using-constructors
今回はFlutterのパフォーマンス改善の中でもconstに着目してまとめました。実装をしていると「Use 'const' with the constructor to improve performance.
」という警告をよく目にするので、この機会にちゃんと理解することができてよかったと思います。