Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to prevent unnecessary re-rendering while using provider? #115

Closed
ghost opened this issue Jun 8, 2019 · 4 comments
Closed

How to prevent unnecessary re-rendering while using provider? #115

ghost opened this issue Jun 8, 2019 · 4 comments

Comments

@ghost
Copy link

ghost commented Jun 8, 2019

I am using provider in my app, but I faced with unnecessary building.

Example

Provider:
             widget1
             widget2
             widget3

Now if I update only widget2 the widget1 & widget3 gets build too, which i dont want.

Here I am wory about performance.

So my expectation is:

I am going to update(build) only the widget I want. because I think if I avoid unnecessary building this may boost the performance.

Now if there is a solution please share it with an example.
think like react-native, as it has shouldComponentUpdate(nextProps, nextState) function, which can be used to avoid unnecessary rendering and boost performance.

@fantasy525
Copy link

fantasy525 commented Jun 10, 2019

@muhammadwfa I agree with you.and You can look at flutter_redux.dart,It maps a new stream,It generated new data types from a bloc instance ,like this:

 stream = _stream.map((_) => widget.converter(widget.store));
 stream = stream.where((vm) {
        final isDistinct = vm != latestValue;// compare old and new
        return isDistinct;
      });

new StoreConnector<int, String>(
                  converter: (store) => store.state.toString(),
                  distinct: true,//true,will compare old  value and new value
                  builder: (context, count) {
                    return new Text(
                      count,
                      style: Theme.of(context).textTheme.display1,
                    );
                  },
                )

but,Come back here.
shouldComponentUpdate(nextProps, nextState) ,I like this.and in google I/O state management video,It seems like we need to write a lot of ChangeNotifier implementations to reduce unnecessary rebuild.But for Provider ,this is the only way can do it, right? @rrousselGit

@fantasy525
Copy link

related issues:
https://github.com/rrousselGit/provider/issues/85

#26

@fantasy525
Copy link

Hi,I get it.I found a solution, @muhammadwfa

class Value<T> extends ValueNotifier{ // ValueNotifier's name is too long
   Value(T value):super(value);
}
class HomeProvider{
  Value<int> age = Value(0);
  Value<String> name = Value('zxf');
  add(){
    age.value++;
  }
  setName() {
    name.value = 'jsy';
  }
}

// home.dart
...
 InkResponse(
              child: ValueListenableBuilder(
                valueListenable: _homeProvider.age,
                builder: (context,value,child){
                  return Text(
                    'Hello${value}',
                    style: TextStyle(
                        color: Color(0xff4A4A4A)
                        ,fontSize: 22,
                        fontWeight: FontWeight.w600
                    ),
                  );
                },
              ),
              onTap: (){
                _homeProvider.add();
              },
...

now, only ValueListenableBuilder and Text rebuild .

@rrousselGit
Copy link
Owner

The typical solution is that, instead of:

ListView.builder(
  itemBuilder: (context, index) {
    final models = Provider.of<List<Model>>(context);
    return MyListItem(models[index]);
  }
)

We'd want to use something like that instead:

ListView.builder(
  itemBuilder: (context, index) {
    return ProxyProvider<List<Model>, ModelItem>(
      builder: (_, models, __) => model[index],
      child: const MyListItem(),
    );
  }
)

where MyListItem obtains the current item through Provider.of<Model> instead of its constructor.
If the item itself is a ChangeNotifier, replace ProxyProvider by ChangeNotifierProxyProvider.

This will automatically update only what's needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants