In a widget hierarchy, how should one go about deciding at which level const should be added? For example, is the following:

const Padding(
  padding: EdgeInsets.symmetric(
    horizontal: LayoutStyles.horizontalPagePadding
  ),
  child: Icon(Icons.search, color: Colors.black),
)

better than, say:

Padding(
  padding: const EdgeInsets.symmetric(
    horizontal: LayoutStyles.horizontalPagePadding
  ),
  child: const Icon(Icons.search, color: Colors.black),
)

If so, why? Does it depend on which element(s) is/are most likely to recur in the program, and hence be canonicalized?


Solution 1: Tree

If you can add const, add it because it will be compile-time constant and it will optimize the usage.

check this answer for details on const constructors:

How does the const constructor actually work?


Solution 2: Nouredine LAMAMRA

here is an explanation of the keyword const and its use: First, to be able to use this keyword the constructor of your widget must be const for example (using flutter widgets ) :

  • you can add the keyword const before EdgeInsets.all but you cant do this with BorderRaduis.circular and the reason is that BorderRaduis.circular is not marked as const.

and the second condition if the constructor is marked as const is to pass a constant value as parametre.

Why we use const keyword ?

  • it's used mostely to increase the performance of your application (avoid instanciation for every call of the build method)

hope that my answer helped you.


Solution 3: dev-aentgs

Depends on that specific part of the Widget tree being constant throughout the Application life cycle. Like the entire Padding widget is not going to change overtime hence make it const. In cases where the child or the subtree is going to change the second approach suits

From the Docs - Performance considerations

If a subtree does not change, cache the widget that represents that subtree and re-use it each time it can be used. It is massively more efficient for a widget to be re-used than for a new (but identically-configured) widget to be created. Factoring out the stateful part into a widget that takes a child argument is a common way of doing this.

Use const widgets where possible. (This is equivalent to caching a widget and re-using it.)

An excerpt from medium article on Inherited Widgets

Use const to build your widgets

Without const, selective rebuilding of the sub-tree does not happen. Flutter creates a new instance of each widget in the sub-tree and calls build() wasting precious cycles especially if your build methods are heavy.


Solution 4: Naslausky

From the Effective Dart: usage, you can see the following example:

Basically, any place where it would be an error to write new instead of const, Dart 2 allows you to omit the const.

Good:

const primaryColors = [
 Color("red", [255, 0, 0]),
 Color("green", [0, 255, 0]),
 Color("blue", [0, 0, 255]),
];

Bad:

const primaryColors = const [
 const Color("red", const [255, 0, 0]),
 const Color("green", const [0, 255, 0]),
 const Color("blue", const [0, 0, 255]),
];

Using your example, and reading the Edge Insets documentation you can see that the symmetric constructor is a const constructor:

const EdgeInsets.symmetric(
{double vertical: 0.0,
double horizontal: 0.0}
)

So the const in this case is optional and recommended to be ommited from the Dart Guidelines.

So, answering your question:

If so, why?

It isn't. It's optional and makes it redundant to read, so it's better to be ommited.

Does it depend on which element(s) is/are most likely to recur in the program, and hence be canonicalized?

You should use for things that are compile time constants, i.e you can figure it's whole value without having to run the program. If you can assure that, you can add const to the constructor of a function you declared, or a value you created. In this way, the compiler can assign a "nickname" to that object and will not need to recreate it everytime it's needed.