Skip to content

Commit

Permalink
perf: bail out if staleTime stays the same
Browse files Browse the repository at this point in the history
  • Loading branch information
TkDodo committed Nov 26, 2024
1 parent 2c453b4 commit e0c2e82
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 14 deletions.
10 changes: 4 additions & 6 deletions packages/query-core/src/__tests__/queryCache.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('queryCache', () => {
const unsubScribeObserver = observer.subscribe(vi.fn())

await waitFor(() => {
expect(events.length).toBe(10)
expect(events.length).toBe(8)
})

expect(events).toEqual([
Expand All @@ -64,11 +64,9 @@ describe('queryCache', () => {
'observerAdded', // 3. Observer added
'observerResultsUpdated', // 4. Observer result updated -> fetching
'updated', // 5. Query updated -> fetching
'updated', // 6. { type: 'stale' }
'observerResultsUpdated', // 7. Observer result updated -> success
'updated', // 8. Query updated -> success
'observerResultsUpdated', // 9. Observer result updated -> stale
'updated', // 6. { type: 'stale' }
'observerResultsUpdated', // 6. Observer result updated -> success
'updated', // 7. Query updated -> success
'updated', // 8. Query updated -> stale
])

queries.forEach((query) => {
Expand Down
6 changes: 2 additions & 4 deletions packages/query-core/src/__tests__/queryObserver.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1002,12 +1002,10 @@ describe('queryObserver', () => {
await sleep(1)
unsubscribe()
expect(results.length).toBe(4)
expect(keys.length).toBe(4)
expect(keys.length).toBe(3)
expect(keys[0]).toBe(null) // First Query - status: 'pending', fetchStatus: 'idle'
expect(keys[1]).toBe(null) // First Query - status: 'pending', fetchStatus: 'fetching'
// we call placeholderData again when result is created due to stale transition
expect(keys[2]).toBe(null)
expect(keys[3]).toBe(key1) // Second Query - status: 'pending', fetchStatus: 'fetching'
expect(keys[2]).toBe(key1) // Second Query - status: 'pending', fetchStatus: 'fetching'

expect(results[0]).toMatchObject({
data: undefined,
Expand Down
16 changes: 12 additions & 4 deletions packages/query-core/src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export class Query<
#defaultOptions?: QueryOptions<TQueryFnData, TError, TData, TQueryKey>
#abortSignalConsumed: boolean
#staleTimeoutId?: ReturnType<typeof setTimeout>
#currentStaleTime?: number

constructor(config: QueryConfig<TQueryFnData, TError, TData, TQueryKey>) {
super()
Expand Down Expand Up @@ -294,17 +295,24 @@ export class Query<
}

updateStaleTimer(): void {
this.#clearStaleTimeout()
const staleTime = this.staleTime()

// same staleTime as last time, so we have nothing to do
if (staleTime === this.#currentStaleTime) {
return
}

this.#clearStaleTimeout()
this.#currentStaleTime = staleTime

const time = timeUntilStale(this.state.dataUpdatedAt, staleTime)

const triggerStale = () => {
this.#notify({ type: 'stale' })
}

if (time === 0) {
// no timer necessary,
if (time === 0 && !this.isStaleByTime(staleTime)) {
// no timer necessary, time zero is always stale,
// but we aren't currently stale, so we instantly trigger it
triggerStale()
return
}
Expand Down

0 comments on commit e0c2e82

Please sign in to comment.