When bloc states with the same objects list one after another bloc library sent just first of them.
I just updating/adding/deleting items in the list.
I do not want to recreate list every time I sending state as it is time consuming.
You could easily find issue in the bloc source code:
_bindEventsToStates method
return state == transition.nextState || _stateController.isClosed;
So as you could see issue appear because of '==' comparison and it is no way to override it to fix this issue.
Could I kindly ask you to fix this issue or add possibility to override it?
I is some other scenarios when this issue appear I just provide certain one I always have.
More over this comparison have no sense as it could be filters for the stream builders someBloc.whereState<SomeState>()
Thanks in advance
Hi @zs-dima 馃憢
This is not an issue but rather how the bloc behaves. Bloc is built around immutability and relies on value equality to optimize state emissions.
It should be pretty straightforward to obtain a brand new list using List.from(existingList..add(newItem)) and emit it.
If you wish to ignore state == transition.nextState then just don't extend Equatable and each state will be treated as a new instance and emitted.
Copy lists is very bad practice and lead to the performance and memory issues specially on the mobile devices.
Hope Felix have to understand it.
So hope bloc library will be fixed soon
And it is just one of possible examples
I could have just notification states one after another for example
yield NotifyState();
and I want handle all of them
Hi @zs-dima 馃憢
Thanks for opening an issue!
As @RollyPeres mentioned, enforcing immutability is a core aspect of the bloc library. Can you share an example app that illustrates the issues you鈥檙e facing?
Regarding your second comment you can continuously yield the same state type (NotifyState) and as long as your state doesn鈥檛 extend Equatable it should work as you expect.
Hope that helps 馃憤
https://github.com/felangel/bloc/issues/1759#issuecomment-696702712
I have no public repository but it is common case to pass lists in the states,
and then yield states continually on filtering or editing/adding item to list/ delete item from list:
var _someList = List<SomeObject>();
filterList() async* {
yield ListUdated(_someList .where((i) => i.id > 0));
}
addItemToList(SomeObject item) async* {
yield ListUdated(_someList..add(item));
}
I saw many cases that this bloc issue affect app but it is just one case I remember.
I agree that immutability is important but developers should be able to choose app performance, memory and etc for some certain cases.
However you took freedom from developers and force even developers who know what they do just being afraid that some others will not care some cases.
@zs-dima can you show some examples where immutable state had a significant performance impact?
@felangel thanks a lot for looking into this issue
In case of quite big list or/and big object we will have issue in this scenario in continually fire filterList(...) on user typing some data, even with debounce/etc:
var _someList = List<SomeObject>();
loadList() async* {
_someList = await api.loadList();
yield ListLoaded(_someList);
}
filterList(String query) async* {
yield ListUdated(_someList .where((i) => i.note.contains(query)));
}
addItemToList(SomeObject item) async* {
yield ListUdated(_someList..add(item));
}
No problem! I understand what you're saying but I personally don't think that the overhead of creating a copy is going to cause a noticeable impact to performance in most cases. Do you have a concrete example that I can run which clearly suffers from performance issues due to List.of?
The whole point of bloc is to make state management predictable and by having an internal, mutable list which determines the next state you lose that predictability because that list can be mutated at any time and have an impact on the next state.
I have no public concrete example right away
But overhead combined from many app parts: serialization/bloc/etc and example above lead to quite big overhead.
Plus UX, performance, memory usage have quite big priority even keeping in mind that bloc library so helpful.
@zs-dima I personally have not run into performance issues due to immutable state. It's far more likely that the performance issues you are experiencing are due to other aspects of the code. In any case, I can't really help without a reproduction sample that clearly illustrates the problem you are facing which is also backed by data (using the dart dev tools for example).
as I told I respect mutability but I do not like idea to take freedom from developers to improve app performance and memory usage for some certain cases when developers know what they do and know price they pay for
@zs-dima I'm not sure why you feel as though your freedom has been taken. You are free to use a different state management solution which supports mutability (ChangeNotifier/Provider or MobX for example). Again, I highly encourage you to profile your application and spend some time understanding what is having the most significant impact to the performance/memory. I am pretty confident that immutable state is not the cause of the performance issues but again feel free to use a different library if you feel it's necessary 馃憤
I know I could solve this issue by override States '==' method (generate random hash or etc), but it looks like quite ugly solution for so advanced library.
So I hope bloc library will be fixed to be able to override _bindEventsToStates method
As I mentioned earlier this is intentional and if you can provide data and a reproduction sample to support your claim, I'm more than happy to work with you to improve the performance of your app 馃憤
It is quite obvious that copy of big list and big objects take memory and performance away.
And mobile apps memory and performance are critical.
Users do not care state management solution - they care app UX.
I could create examples later but for now bloc force developers to use ugly States '==' override instead.
I would argue that on most devices this is not really an issue and is more of a premature, unnecessary optimization. Closing this issue for now since I don't feel like there is anything actionable.
Feel free to include a link to an example with performance reports and I'm happy to continue the conversation 馃憤
I sublimed related issue till create example:
https://github.com/felangel/bloc/issues/1769