mobxjs / mobx.dart

MobX for the Dart language. Hassle-free, reactive state-management for your Dart and Flutter apps.
https://mobx.netlify.app
MIT License
2.39k stars 311 forks source link

Observer.optimized #952

Closed subzero911 closed 10 months ago

subzero911 commented 10 months ago

I already did a PR https://github.com/mobxjs/mobx.dart/pull/909 but I accidentally deleted the forked repo. So I made it again and a little bit better.

Mostly you try to make Observer as small as possible. But sometimes you'll want to exclude the widget subtree from re-render and improve the performance.

Real world examples: 1) You have a colored Container with some heavy widgets inside (like ListView with shrinkWrap: true). You want to change the color by Observable, but don't want to rebuild the whole ListView. 2) You have some fancy animation driven by Observable. You want to animate the widget and want to preserve its children from being rebuilt.

I introduce the new Observer.optimized which allows you to exclude the child branch. Usage:

   Observer.optimized(
     builderOptimized: (context, child) => FooWidget(foo: foo, child: child),
     child: BarWidget(), // is not rebuilt
   ),

Solves https://github.com/mobxjs/mobx.dart/issues/551

@amondnet @fzyzcjy


Pull Request Checklist

codecov[bot] commented 10 months ago

Codecov Report

Merging #952 (bf2623f) into master (7510ee4) will increase coverage by 0.00%. The diff coverage is 100.00%.

Additional details and impacted files [![Impacted file tree graph](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952/graphs/tree.svg?width=650&height=150&src=pr&token=YjGMFvwbrl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs)](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) ```diff @@ Coverage Diff @@ ## master #952 +/- ## ======================================= Coverage 98.99% 98.99% ======================================= Files 57 57 Lines 1992 1998 +6 ======================================= + Hits 1972 1978 +6 Misses 20 20 ``` | [Flag](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) | Coverage Δ | | |---|---|---| | [flutter_mobx](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) | `100.00% <100.00%> (ø)` | | | [mobx](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) | `98.55% <ø> (ø)` | | | [mobx_codegen](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) | `100.00% <ø> (ø)` | | Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs#carryforward-flags-in-the-pull-request-comment) to find out more. | [Files](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) | Coverage Δ | | |---|---|---| | [flutter\_mobx/lib/src/observer.dart](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs#diff-Zmx1dHRlcl9tb2J4L2xpYi9zcmMvb2JzZXJ2ZXIuZGFydA==) | `100.00% <100.00%> (ø)` | | ------ [Continue to review full report in Codecov by Sentry](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs) > `Δ = absolute (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs). Last update [7510ee4...bf2623f](https://app.codecov.io/gh/mobxjs/mobx.dart/pull/952?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mobxjs).
subzero911 commented 10 months ago

@pavanpodila done. I renamed .optimized to .withChild and builderOptimized to builderWithChild I have no idea how to implement "withChildren" constructor to "exclude subtrees by map keys", and I don't think we actually need it. You can use a Column(children: [...]) as a child, or you can use a composition of Observers.

I applied the same technique which was used in AnimatedBuilder, and provider's Consumer and Selector - they all have the child parameter only. Refer to https://api.flutter.dev/flutter/widgets/AnimatedBuilder-class.html , "Performance optimizations" for details. They don't have any multiple children version.

pavanpodila commented 10 months ago

@all-contributors add @subzero911 for code

allcontributors[bot] commented 10 months ago

@pavanpodila

@subzero911 already contributed before to code