I’ve started using Bloc in my project. I’ve one confusion that I want to clear. Suppose I have got the following cubits:
--- Auth Cubit
--- Category Cubit
--- Cart Cubit
--- Orders Cubit
Now, in order to add them to the project I’ve two options. Either I use MultiBlocProvider
and initialized all of them in the main.dart
app or I use scopped approach. In the case of scopped approach, flutter will initialize it over and over.
From my understanding, if I initialize providers globally I will be able to remove or update them easily. However, in scopped case, I’ve to change it in multiple classes.
I want to know which approach is best performance-wise and what could be the pros and cons of both approaches.
4
Answers
I haven‘t measured the performance of my approach, but my approach is the following:
Bloc‘s that use the same data multiple times in a session, I instantiate in main or app. This would be auth. and cart, maybe category.
Bloc‘s that always run with a new set of data, I instantiate on occasion such as editing an entry of a list of things. This might be Order in your case, if this is the process of checking-out
According to flutter_bloc
Hence it is better to use
MultiBlocProvider
and initialize all the Cubits at the start of the app. Performance in taken care by theBlocProvider
I would say that using a global
BlocProvider
or a scoped one really depends on the use of it, as in your example you did say that you have an AuthCubit
, I assume that this refers to Authentication, right?This cubit should handle/listen to user authentication status across the whole app, so you will need to make it accessible by a global bloc provider, otherwise, if you choose as an example to make it available only on a login/sign-up screens, a simple Flutter navigation will make a new widget sub-tree in the
Navigator
widget inMaterialApp
, when you will try to logout as an example from the new screen, it will throw you the usual issue ofError: Could not find the correct BlocProvider...
, unless you will pass it withBlocProvider.value
, which is very painful and lead you to unnecessary work, right?So here before thinking about what is the more preferment, think about the requirement of your app with that specific bloc!
for another example, such as the categories
Cubit
, if you fetch them to from a database for example using a repository, a global cubit will be initialized just once time for the global app state, fetching all categories available and showing them, while the user navigates between the screens, the categories will be available always as the previous state ( you might give users opportunity to reload them ), but setting here a nested cubit will initialize the cubit with the repository each time the screen is pushed and popped throw theNavigator
, which leads to unnecessary fetches from the database ( and if you use Firebase Firestore, this will lead to unnecessary billed reads in the app ), so also for this you should consider using a global cubit.I hope you understand the idea that each case requires you to take a decision while developing the app!
Now let’s talk about the performance of each one:
As from the official BloC documentation:
Meaning that whenever you do declare a
BlocProvider
widget, all that happens is that the declaration of thecreate
function that returns the bloc only gets saved in the memory, so either by declaring a nested one or a global one, the same memory resource will get taken, when you make a lookup for that bloc for the first time, the saved bloc will be initialized, here time complexity of the lookup operation will depend on the size of the widget tree, the BlocProvider will look up every single widget in the tree until it finds the right cubit/bloc, so here using a globalBlocProvider
in themain.dart
will lead to taking more time finding it than a bloc/cubit that is being passed across screens with aBlocProvider.value
.But here you need to ask yourself, does look up for the cubit/bloc only one time and use as many times as you want in the app worth it than making a new short look-up every time the widget sub-tree is inserted/removed from the widget tree.