escamoteur / watch_it

MIT License
103 stars 8 forks source link

watchFuture tanks performance #13

Closed alexanderameye closed 9 months ago

alexanderameye commented 9 months ago

Hello,

I have this function that returns a future of whether a species is favorited by the user. (The favorite status is stored on the device in a local database, Isar)

image

I then have a widget like this where the favorite status is watched using watchFuture inside of the build method. The favorite status is then used in the widget to show an icon (not shown in image)

image

This works functionally, and when I remove the favorite status manually, the UI is instantly updated.

However, this completely tanks performance: I see that the widgets are rebuilt every frame.

image

I understand that a rebuild needs to happen so that the widget can be instantly updated to show the new favorited status.

But how can I improve the performance?

I'm thinking that only really the favorite status widget needs to be rebuilt (I use a ChoiceChip to display the favorite status)

image

But the rest of the widgets should not be rebuilt? How can I achieve this?

Should I move the ChoiceChip to its own widget, call watchFuture only there in the build method so that the other widgets do not need to be rebuilt?

I'm pretty new to flutter and state management so any advice would be great. Or if there is a better way to use watch_it to achieve this, basically my use case seems pretty common.

Thanks a lot!

escamoteur commented 9 months ago

I think your problems has different aspects

  1. yes putting the Chip into its own widget would only rebuild that widget which would improve performance.
  2. The bigger problem in my opinion is that you get e new future on every rebuild because you call that function that calls into ISAR.

Doesn't ISAR also offer a Stream based API that would send a new data item whenever its data changes? Futures are great for one time calls but not for observing an object

otherwise I would recommend adding a business logic layer in between that checks the status of that field in regular intervalls and then updates a ValueListenable that then is watched by watchValue.

I hope that helps :-)