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

perf(store): run change detection once for all selectors when asynchronous action has been completed #1828

Merged
merged 2 commits into from
May 21, 2022

Conversation

arturovt
Copy link
Member

@arturovt arturovt commented Mar 2, 2022

No description provided.

@arturovt arturovt changed the title perf(store): do not run change detection whenever the selectors emits perf(store): do not run change detection whenever selectors emit Mar 9, 2022
@@ -87,7 +98,9 @@ export class Store {
* Allow the user to subscribe to the root of the state
*/
subscribe(fn?: (value: any) => void): Subscription {
return this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy)).subscribe(fn);
return this._selectableStateStream
.pipe(leaveNgxs(this._internalExecutionStrategy))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still necessary since we are using the new shared stream?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary in case the Store class is subscribed outside of the Angular zone.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that the new _selectableStateStream would handle ensuring that the subscribers are notified in the correct zone? But maybe there would be no guarantee for new subscriptions where we first receive the current value that already exists in the stream?
If this is the case, then would we not also have to do this if the store.select is subscribed to outside of the Angular Zone?

Copy link
Member Author

@arturovt arturovt Mar 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _selectableStateStream cannot ensure that completely. Given this example:

constructor(store: Store, ngZone: NgZone) {
  ngZone.runOutsideAngular(() => {
    setTimeout(() => {
      store.subscribe(() => console.log(Zone.current)); // will log angular
    }, 3000);
  });
}

Otherwise, it'll log <root>. The _selectableStateStream is an optimization that re-enters the zone before publishReplay() so that we trigger a single tick() for all existing subscriptions.

packages/store/src/store.ts Outdated Show resolved Hide resolved
@@ -87,7 +98,9 @@ export class Store {
* Allow the user to subscribe to the root of the state
*/
subscribe(fn?: (value: any) => void): Subscription {
return this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy)).subscribe(fn);
return this._selectableStateStream
.pipe(leaveNgxs(this._internalExecutionStrategy))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that the new _selectableStateStream would handle ensuring that the subscribers are notified in the correct zone? But maybe there would be no guarantee for new subscriptions where we first receive the current value that already exists in the stream?
If this is the case, then would we not also have to do this if the store.select is subscribed to outside of the Angular Zone?

@arturovt arturovt changed the title perf(store): do not run change detection whenever selectors emit perf(store): run change detection once for all selectors when asynchronous action has been completed Mar 10, 2022
@markwhitfeld
Copy link
Member

@arturovt is this still in draft?
Is there anything you need from me to get this ready?

@arturovt arturovt marked this pull request as ready for review May 21, 2022 21:58
@arturovt
Copy link
Member Author

Glad you're back! No, I've made is as a draft initially, but this is ready now to be merged (if all requirements are passed).

Copy link
Member

@markwhitfeld markwhitfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with this. Just need to fix the failing bundlesizes ;-)
Might be worth merging master into this branch before doing this too.

@arturovt
Copy link
Member Author

arturovt commented May 21, 2022

Updated, hope it passes, this bundlesize is such annoying guy... 😸

@arturovt arturovt merged commit 6ba2ac1 into master May 21, 2022
@arturovt arturovt deleted the fix/cd branch May 21, 2022 22:30
@markwhitfeld
Copy link
Member

markwhitfeld commented May 21, 2022

I couldn't agree more!!! See #1764

@markwhitfeld markwhitfeld added this to the v3.7.4 milestone Jun 10, 2022
crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Jun 17, 2022
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@ngxs/form-plugin](https://github.com/ngxs/store) | dependencies | patch | [`3.7.3` -> `3.7.4`](https://renovatebot.com/diffs/npm/@ngxs%2fform-plugin/3.7.3/3.7.4) |
| [@ngxs/storage-plugin](https://github.com/ngxs/store) | dependencies | patch | [`3.7.3` -> `3.7.4`](https://renovatebot.com/diffs/npm/@ngxs%2fstorage-plugin/3.7.3/3.7.4) |
| [@ngxs/store](https://github.com/ngxs/store) | dependencies | patch | [`3.7.3` -> `3.7.4`](https://renovatebot.com/diffs/npm/@ngxs%2fstore/3.7.3/3.7.4) |

---

### Release Notes

<details>
<summary>ngxs/store</summary>

### [`v3.7.4`](https://github.com/ngxs/store/blob/HEAD/CHANGELOG.md#&#8203;374-2022-06-09)

[Compare Source](ngxs/store@v3.7.3...v3.7.4)

-   Build: include support for Angular 14 [#&#8203;1850](ngxs/store#1850)
-   Fix: Do not re-use the global `Store` instance between different apps [#&#8203;1740](ngxs/store#1740) and [#&#8203;1804](ngxs/store#1804)
-   Fix: Handle mixed async scenarios for action handlers [#&#8203;1762](ngxs/store#1762)
-   Fix: An action with cancelUncompleted enabled should unsubscribe before the next action handler is called [#&#8203;1763](ngxs/store#1763)
-   Fix: Do not run `Promise.then` within synchronous tests when decorating factory [#&#8203;1753](ngxs/store#1753)
-   Fix: Provide `NoopNgxsExecutionStrategy` explicitly when the zone is nooped [#&#8203;1819](ngxs/store#1819)
-   Fix: Complete the state stream once the root view is removed [#&#8203;1830](ngxs/store#1830)
-   Fix: Be more explicit when checking if Angular is in test mode [#&#8203;1831](ngxs/store#1831), [#&#8203;1832](ngxs/store#1832)
-   Fix: Devtools Plugin - Do not connect to devtools when the plugin is disabled [#&#8203;1761](ngxs/store#1761)
-   Fix: Router Plugin - Cleanup subscriptions when the root view is destroyed [#&#8203;1754](ngxs/store#1754)
-   Fix: WebSocket Plugin - Cleanup subscriptions and close the connection when the root view is destroyed [#&#8203;1755](ngxs/store#1755)
-   Fix: Storage Plugin - Only restore state if key matches `addedStates` [#&#8203;1746](ngxs/store#1746)
-   Fix: Forms Plugin - Do not destructure primitive types [#&#8203;1845](ngxs/store#1845)
-   Performance: Tree-shake errors and warnings [#&#8203;1732](ngxs/store#1732)
-   Performance: Tree-shake `ConfigValidator`, `HostEnvironment` and `isAngularInTestMode` [#&#8203;1741](ngxs/store#1741)
-   Performance: Tree-shake `SelectFactory` [#&#8203;1744](ngxs/store#1744)
-   Performance: Tree-shake `deepFreeze` [#&#8203;1819](ngxs/store#1819)
-   Performance: Run change detection once for all selectors when asynchronous action has been completed [#&#8203;1828](ngxs/store#1828)
-   Performance: Router Plugin - Tree-shake `isAngularInTestMode()` [#&#8203;1738](ngxs/store#1738)
-   Performance: Tree-shake `isAngularInTestMode()` [#&#8203;1739](ngxs/store#1739)
-   Performance: Storage Plugin - Tree-shake `console.*` calls and expand error messages [#&#8203;1727](ngxs/store#1727)
-   CI: Bundlesize checks should run reliably [#&#8203;1812](ngxs/store#1812)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Co-authored-by: cabr2-bot <[email protected]>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1401
Co-authored-by: Calciumdibromid Bot <[email protected]>
Co-committed-by: Calciumdibromid Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants