Skip to content

Commit 5499577

Browse files
AghassidavidaghassiTkDodo
authored
fix(perf): improve long running task performance in query core (#8107)
* fix: improve long running task performance in query core This addresses two hot spots we have noticed on a large scale enterprise app when profiling with chrome. These changes help to cut down on long running tasks when there are many query calls on the page * refactor: remove two more arrays to be more efficient * refactor: remove queryObserver improvement from PR * refactor: packages/query-core/src/queryObserver.ts remove --------- Co-authored-by: davidaghassi <[email protected]> Co-authored-by: Dominik Dorfmeister <[email protected]>
1 parent 44b70f1 commit 5499577

File tree

1 file changed

+30
-46
lines changed

1 file changed

+30
-46
lines changed

packages/query-core/src/queriesObserver.ts

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -207,59 +207,43 @@ export class QueriesObserver<
207207
#findMatchingObservers(
208208
queries: Array<QueryObserverOptions>,
209209
): Array<QueryObserverMatch> {
210-
const prevObservers = this.#observers
211210
const prevObserversMap = new Map(
212-
prevObservers.map((observer) => [observer.options.queryHash, observer]),
211+
this.#observers.map((observer) => [observer.options.queryHash, observer]),
213212
)
214213

215-
const defaultedQueryOptions = queries.map((options) =>
216-
this.#client.defaultQueryOptions(options),
217-
)
218-
219-
const matchingObservers: Array<QueryObserverMatch> =
220-
defaultedQueryOptions.flatMap((defaultedOptions) => {
221-
const match = prevObserversMap.get(defaultedOptions.queryHash)
222-
if (match != null) {
223-
return [{ defaultedQueryOptions: defaultedOptions, observer: match }]
224-
}
225-
return []
226-
})
227-
228-
const matchedQueryHashes = new Set(
229-
matchingObservers.map((match) => match.defaultedQueryOptions.queryHash),
230-
)
231-
const unmatchedQueries = defaultedQueryOptions.filter(
232-
(defaultedOptions) => !matchedQueryHashes.has(defaultedOptions.queryHash),
233-
)
214+
const observers: Array<QueryObserverMatch> = []
234215

235-
const getObserver = (options: QueryObserverOptions): QueryObserver => {
216+
queries.forEach((options) => {
236217
const defaultedOptions = this.#client.defaultQueryOptions(options)
237-
const currentObserver = this.#observers.find(
238-
(o) => o.options.queryHash === defaultedOptions.queryHash,
239-
)
218+
const match = prevObserversMap.get(defaultedOptions.queryHash)
219+
if (match) {
220+
observers.push({
221+
defaultedQueryOptions: defaultedOptions,
222+
observer: match,
223+
})
224+
} else {
225+
const existingObserver = this.#observers.find(
226+
(o) => o.options.queryHash === defaultedOptions.queryHash,
227+
)
228+
observers.push({
229+
defaultedQueryOptions: defaultedOptions,
230+
observer:
231+
existingObserver ??
232+
new QueryObserver(this.#client, defaultedOptions),
233+
})
234+
}
235+
})
236+
237+
return observers.sort((a, b) => {
240238
return (
241-
currentObserver ?? new QueryObserver(this.#client, defaultedOptions)
239+
queries.findIndex(
240+
(q) => q.queryHash === a.defaultedQueryOptions.queryHash,
241+
) -
242+
queries.findIndex(
243+
(q) => q.queryHash === b.defaultedQueryOptions.queryHash,
244+
)
242245
)
243-
}
244-
245-
const newOrReusedObservers: Array<QueryObserverMatch> =
246-
unmatchedQueries.map((options) => {
247-
return {
248-
defaultedQueryOptions: options,
249-
observer: getObserver(options),
250-
}
251-
})
252-
253-
const sortMatchesByOrderOfQueries = (
254-
a: QueryObserverMatch,
255-
b: QueryObserverMatch,
256-
): number =>
257-
defaultedQueryOptions.indexOf(a.defaultedQueryOptions) -
258-
defaultedQueryOptions.indexOf(b.defaultedQueryOptions)
259-
260-
return matchingObservers
261-
.concat(newOrReusedObservers)
262-
.sort(sortMatchesByOrderOfQueries)
246+
})
263247
}
264248

265249
#onUpdate(observer: QueryObserver, result: QueryObserverResult): void {

0 commit comments

Comments
 (0)