Skip to content

perf(persist): subscriber calls persistQueryClientStore only on cache-related events#4884

Merged
TkDodo merged 6 commits into
TanStack:mainfrom
emzet93:main
Feb 18, 2023
Merged

perf(persist): subscriber calls persistQueryClientStore only on cache-related events#4884
TkDodo merged 6 commits into
TanStack:mainfrom
emzet93:main

Conversation

@emzet93

@emzet93 emzet93 commented Jan 26, 2023

Copy link
Copy Markdown
Contributor

By default persistQueryClientSubscribe was calling persistQueryClientSave on every single change in query cache.
It was also triggered by events like observerOptionsUpdated which are emitted very often, usually on every single re-render of component/hook using useQuery.

For performance improvement, we can limit list of events triggering persistQueryClientSave only for those, which actually have influence on the cache itself.

@vercel

vercel Bot commented Jan 26, 2023

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated
query ⬜️ Ignored (Inspect) Feb 18, 2023 at 11:00AM (UTC)

@codesandbox-ci

codesandbox-ci Bot commented Jan 26, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 1e8c668:

Sandbox Source
@tanstack/query-example-react-basic-typescript Configuration
@tanstack/query-example-solid-basic-typescript Configuration
@tanstack/query-example-svelte-basic Configuration
@tanstack/query-example-vue-basic Configuration

Comment thread packages/query-persist-client-core/src/persist.ts Outdated

@louis-young louis-young left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for putting this together 🚀

Is it worth reusing a predicate function here? Perhaps it's a hasty abstraction, but something along the lines of isCacheableEventType.

Edit: see suggestion here 🙂

* Checks if emitted event is about cache change and not about observers.
* Useful for persist, where we only want to trigger save when cache is changed.
*/
function isCacheableEventType(eventType: NotifyEventType) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@TkDodo I placed this function here as in internal one for now. Let me know if there is a better place for that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should check that Dominik is happy with this idea, but I think we could start on the tests for the new behaviour if you're up for it 🙂

@emzet93 emzet93 Jan 27, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure I am. Although no idea where to start 😅

@louis-young louis-young Jan 27, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like the relevant tests are here:

https://github.com/TanStack/query/blob/main/packages/query-persist-client-core/src/__tests__/persist.test.ts#L22

I think this is probably going to be non-trivial to test. I think we'd essentially be looking to assert on when persistClient is and isn't called on the mocked persister, and probably on the state of the restored client. I think the interesting part here will be building and manipulating queries/mutations to get into the right state to make these assertions though.

I'd be happy to take a look but I won't have time for a little while, although I think Dominik said he'd be willing to lend a hand 🤞

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

awesome, thanks!

@codecov-commenter

codecov-commenter commented Jan 27, 2023

Copy link
Copy Markdown

Codecov Report

Base: 91.84% // Head: 91.87% // Increases project coverage by +0.03% 🎉

Coverage data is based on head (1e8c668) compared to base (aa94a94).
Patch coverage: 90.00% of modified lines in pull request are covered.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4884      +/-   ##
==========================================
+ Coverage   91.84%   91.87%   +0.03%     
==========================================
  Files         111      111              
  Lines        4155     4171      +16     
  Branches     1079     1081       +2     
==========================================
+ Hits         3816     3832      +16     
  Misses        318      318              
  Partials       21       21              
Impacted Files Coverage Δ
packages/query-core/src/mutationCache.ts 100.00% <ø> (ø)
packages/query-core/src/queryCache.ts 100.00% <ø> (ø)
...s/query-persist-client-core/src/__tests__/utils.ts 89.47% <81.81%> (-10.53%) ⬇️
packages/query-persist-client-core/src/persist.ts 46.15% <100.00%> (+9.98%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@TkDodo TkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the only thing missing for me is tests. What we would need is some sort of test that writes a custom persister that basically just tracks with jest.fn how often we call the persistence write function, then create an observer, mount and unmount, maybe set some options etc and then make sure that we call the write function not too often :)

Comment on lines +61 to +65
const CACHEABLE_EVENT_TYPES: Array<NotifyEventType> = [
'added',
'removed',
'updated',
]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

could we move this out of the function isCacheableEventType ? There's no need to re-create this every time.

'updated',
]

return CACHEABLE_EVENT_TYPES.includes(eventType)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd also prefer if we'd name this just const cacheableEventTypes.

@emzet93

emzet93 commented Feb 13, 2023

Copy link
Copy Markdown
Contributor Author

the only thing missing for me is tests. What we would need is some sort of test that writes a custom persister that basically just tracks with jest.fn how often we call the persistence write function, then create an observer, mount and unmount, maybe set some options etc and then make sure that we call the write function not too often :)

Thanks, it all makes sense. I'm not sure about my availability this week, but I hope I'll find some time to add it :)

@TkDodo TkDodo merged commit b32da31 into TanStack:main Feb 18, 2023
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

Successfully merging this pull request may close these issues.

5 participants