19

Numerous questions relating to building Flutter UIs come down to the wrong BuildContext (such as showing a SnackBar). The answers usually offer either of using a Builder or using a GlobalKey. Both work, but I noticed that the documentation for GlobalKey states:

Global keys are relatively expensive. If you don't need any of the features listed above, consider using a Key, ValueKey, ObjectKey, or UniqueKey instead.

The features referred to are unique identification and subtree re-parenting. Is the "relative expense" of using a GlobalKey for these circumstances reason enough to use a Builder instead?

Derek Lakin
  • 16,179
  • 36
  • 51

2 Answers2

44

The real reason we tend to avoid GlobalKey is not about performance. It is more related to the fact that it breaks a few patterns in flutter.

Widgets by definition should not be able to access concrete information of other widgets (such as their size or position). And GlobalKey grant the ability to access such information; allowing peoples to do anti-pattern stuff.

Think of GlobalKey as a mean to eject the reactive layer of Flutter.

A few examples of what peoples are tempted to do using GlobalKey :

  • Having a public singleton GlobalKey. Used as a mean to not lift the state up. Making interaction between widgets hard to predict, as the relationship isn't one-sided anymore (parent -> children becomes a two-way relationship)
  • Using GlobalKey to compute the size of a layout. Then trigger a re-render with this information. This instead is the role of RenderObject and shouldn't be done in widgets. It makes layout much harder to maintain

Builder and similar on the other hand don't break these patterns. As, by definition Builder does nothing. It's just a neat way of using a different BuildContext.

This usually means that if you can solve your layout problem using Builder instead of GlobalKey, you're on the right track to a maintainable layout.


When to use GlobalKey then?

Well, if you can, never. Try to instead use things such as context.ancestorStateOfType or context.inheritWidgetOfExtactType. You may also want to consider creating a custom RenderObject for a specific layout. RenderObject combined with parentData may also be what you want if you need a relationship between parent/children

This can more complicated though. It can consume more time than you want. Or you may fall into an edge-case that is hard to implement using the current API.

In such situations, it is ok to use GlobalKey as long as you know the potential consequences.

Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • Thanks for the detailed answer; that makes sense. Perhaps the docs should be clearer on the real reasoning and some use cases on when it's OK to use `GlobalKey` and when it's not :) – Derek Lakin Jul 30 '18 at 08:22
  • @rémi-rousselet, To compute the size of a layout , instead of using Global key what to use? – abdullah_bd Feb 13 '23 at 13:37
9

GlobalKey being expensive is most likely related to situations where you might need lots of keys, like for the children of a ListView.

I doubt the cost of a GlobalKey for a SnackBar will matter. It's unlikely that you create a lot of them.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    This is what you were saying. Read it here now. I am also updating that solution by inserting a link of this answer plus upvoting it too. –  Dec 10 '18 at 14:37
  • so is it okay in terms of performance and memory to use `GlobalKey` to show `Snackbar` as long as we have just one `GlobalKey` in the entire widget assigned to the `Scaffold`? –  Dec 20 '18 at 13:10
  • 2
    I think so. Don't use GlobalKey for items in a list with hundreds of items. – Günter Zöchbauer Dec 20 '18 at 13:15
  • But why? Can you please explain, why one should not use GlobalKeys for many items? Does it decrease my performance? – Marwin Lebensky Jun 24 '22 at 09:02
  • 1
    The Flutter documentation states, that it is expensive (lots of computation). So if you have some specific situation where you benefit from it, it's probably a good idea to use it. If it's not strictly necessary, better try to avoid it. – Günter Zöchbauer Jun 24 '22 at 11:02