Defer chores to idle time
Run analytics, saves and prefetches in requestIdleCallback, not inline.
From vercel-react-best-practices, rule js-request-idle-callback.
Search with side chores
Press Type, or type yourself. Watch when results paint.
Chores inlineBad
Keystroke to paint –
analytics.track(…) // inlinerequestIdleCallbackGood
Keystroke to paint –
requestIdleCallback(() => track(…))function handleSearch(query: string) {
const results = searchItems(query)
setResults(results)
// Nobody waits on these: run them when the browser is idle
requestIdleCallback(() => analytics.track('search', { query }))
requestIdleCallback(() => saveToRecentSearches(query))
requestIdleCallback(() => prefetchTopResults(results.slice(0, 3)))
}
Chunk a big job
Process 2,000 items. Each square is one frame.
One long taskBad
0 items · 0 dropped frames
items.forEach(processItem)Idle chunksGood
0 items · 0 dropped frames
while (deadline.timeRemaining() > 0)function processLargeDataset(items: Item[]) {
let index = 0
function processChunk(deadline: IdleDeadline) {
while (index < items.length && deadline.timeRemaining() > 0) {
processItem(items[index])
index++
}
if (index < items.length) requestIdleCallback(processChunk)
}
requestIdleCallback(processChunk)
}
// Fallback where it's missing
const scheduleIdleWork = window.requestIdleCallback ?? ((cb) => setTimeout(cb, 1))
Why it matters, pros and cons
Why it matters
Work nobody waits for still delays the frame that shows what they typed.
Pros
- Keystrokes paint first.
- Long jobs stop dropping frames.
- A
timeoutstill guarantees it runs.
Cons
- Not for results the user is waiting on.
- Not in every browser; fall back to
setTimeout. - A busy page may never go idle; set a timeout.