15

I've been struggling to understand when ChangeNotifier is preferred over Rxdart's Observable, or streams in general.

According to Flutter's docs:

A class that can be extended or mixed in that provides a change notification API using VoidCallback for notifications.

ChangeNotifier is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners).

Still, I'm not sure what ChangeNotifier can offer that an Observable or Stream cannot.

Community
  • 1
  • 1
Eliya Cohen
  • 10,716
  • 13
  • 59
  • 116
  • `ChangeNotifier` can be used anywhere where `Listenable` is expected: for example for fast updating `CustomPainter` - you cannot use any `Stream` for that – pskink Nov 06 '19 at 09:39
  • @pskink and wouldn't it be achievable by using stream at the same cost of performance? – Eliya Cohen Nov 06 '19 at 09:41
  • 1
    no, `CustomPainter` accepts `Listenable` – pskink Nov 06 '19 at 09:43
  • @pskink Ok, so my question is - for what reasons flutter would implement ChangeNotifer or Listenable when you can achieve the same goal by using streams? or you can't? – Eliya Cohen Nov 06 '19 at 09:48
  • 1
    they **could** use `stream`s everywhere but it seems that `ChangeNotifer` is faster and where the performance is important they use it – pskink Nov 06 '19 at 09:50
  • 3
    The `ChangeNotifier` is synchronous, streams are asynchronous (if they aren't, they are breaking the `Stream` contract and code might start acting weirdly). Not having the overhead of going through the event loop is one of the reasons the `ChangeNotifier` is more efficient than the more general asynchronous streams. – lrn Nov 06 '19 at 14:41
  • @Irn I see this kind of comments all the time in flutter source code (use SynchronousFuture to bypass the event loop). How impactful would going through the event loop really be ? Isn't that preemptive optimisation at the expense of readability ? – Ced Feb 19 '21 at 17:44

1 Answers1

6

Some updates since you asked this question

  • Observable is deprecated and you can just use extension functions on Stream
  • ChangeNotifier performance: O(1) for adding listeners and O(N) for removing listeners and dispatching notifications

But I would focus less on performance and more on the use-case. ValueNotifier is a lighter-weight solution, but not as robust as Streams.

This Reddit thread does a great job describing the difference in use-case. As does this StackOverflow post.

But to summarize:

  • Streams are great when working in your model/networking layer (or business logic). "Streams represent a series of events or pieces of information (from zero to infinite) that are produced from a source. This naturally makes sense for network packets, video frames, analytics events, error reporting, etc."
  • ValueNotifier is great for relaying state changes back to your UI. "If you have an object with members that might change, and you want to know when some or all of them change, then all you need to do is mixin ChangeNotifier within that class, and then invoke notifyListeners whenever something changes."
Kyle Venn
  • 4,597
  • 27
  • 41