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

fix: improve long running task performance in query core #8107

Merged
merged 12 commits into from
Oct 9, 2024
Merged
76 changes: 30 additions & 46 deletions packages/query-core/src/queriesObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,59 +207,43 @@
#findMatchingObservers(
queries: Array<QueryObserverOptions>,
): Array<QueryObserverMatch> {
const prevObservers = this.#observers
const prevObserversMap = new Map(
prevObservers.map((observer) => [observer.options.queryHash, observer]),
this.#observers.map((observer) => [observer.options.queryHash, observer]),
)

const defaultedQueryOptions = queries.map((options) =>
this.#client.defaultQueryOptions(options),
)

const matchingObservers: Array<QueryObserverMatch> =
defaultedQueryOptions.flatMap((defaultedOptions) => {
const match = prevObserversMap.get(defaultedOptions.queryHash)
if (match != null) {
return [{ defaultedQueryOptions: defaultedOptions, observer: match }]
}
return []
})

const matchedQueryHashes = new Set(
matchingObservers.map((match) => match.defaultedQueryOptions.queryHash),
)
const unmatchedQueries = defaultedQueryOptions.filter(
(defaultedOptions) => !matchedQueryHashes.has(defaultedOptions.queryHash),
)
const observers: Array<QueryObserverMatch> = []

const getObserver = (options: QueryObserverOptions): QueryObserver => {
queries.forEach((options) => {
const defaultedOptions = this.#client.defaultQueryOptions(options)
const currentObserver = this.#observers.find(
(o) => o.options.queryHash === defaultedOptions.queryHash,
)
const match = prevObserversMap.get(defaultedOptions.queryHash)
if (match) {
observers.push({
defaultedQueryOptions: defaultedOptions,
observer: match,
})
} else {
const existingObserver = this.#observers.find(
(o) => o.options.queryHash === defaultedOptions.queryHash,

Check warning on line 226 in packages/query-core/src/queriesObserver.ts

View check run for this annotation

Codecov / codecov/patch

packages/query-core/src/queriesObserver.ts#L226

Added line #L226 was not covered by tests
)
observers.push({
defaultedQueryOptions: defaultedOptions,
observer:
existingObserver ??
new QueryObserver(this.#client, defaultedOptions),
})
}
})

return observers.sort((a, b) => {
return (
currentObserver ?? new QueryObserver(this.#client, defaultedOptions)
queries.findIndex(
(q) => q.queryHash === a.defaultedQueryOptions.queryHash,
) -
queries.findIndex(
(q) => q.queryHash === b.defaultedQueryOptions.queryHash,
)
)
}

const newOrReusedObservers: Array<QueryObserverMatch> =
unmatchedQueries.map((options) => {
return {
defaultedQueryOptions: options,
observer: getObserver(options),
}
})

const sortMatchesByOrderOfQueries = (
a: QueryObserverMatch,
b: QueryObserverMatch,
): number =>
defaultedQueryOptions.indexOf(a.defaultedQueryOptions) -
defaultedQueryOptions.indexOf(b.defaultedQueryOptions)

return matchingObservers
.concat(newOrReusedObservers)
.sort(sortMatchesByOrderOfQueries)
})
}

#onUpdate(observer: QueryObserver, result: QueryObserverResult): void {
Expand Down
Loading