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(…) // inline
    requestIdleCallbackGood

      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 timeout still 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.