Files
bipproduction 39d659acd0 skills
2026-04-01 10:43:03 +08:00

2.6 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Defer Non-Critical Work with requestIdleCallback MEDIUM keeps UI responsive during background tasks javascript, performance, idle, scheduling, analytics

Defer Non-Critical Work with requestIdleCallback

Impact: MEDIUM (keeps UI responsive during background tasks)

Use requestIdleCallback() to schedule non-critical work during browser idle periods. This keeps the main thread free for user interactions and animations, reducing jank and improving perceived performance.

Incorrect (blocks main thread during user interaction):

function handleSearch(query: string) {
  const results = searchItems(query)
  setResults(results)

  // These block the main thread immediately
  analytics.track('search', { query })
  saveToRecentSearches(query)
  prefetchTopResults(results.slice(0, 3))
}

Correct (defers non-critical work to idle time):

function handleSearch(query: string) {
  const results = searchItems(query)
  setResults(results)

  // Defer non-critical work to idle periods
  requestIdleCallback(() => {
    analytics.track('search', { query })
  })

  requestIdleCallback(() => {
    saveToRecentSearches(query)
  })

  requestIdleCallback(() => {
    prefetchTopResults(results.slice(0, 3))
  })
}

With timeout for required work:

// Ensure analytics fires within 2 seconds even if browser stays busy
requestIdleCallback(
  () => analytics.track('page_view', { path: location.pathname }),
  { timeout: 2000 }
)

Chunking large tasks:

function processLargeDataset(items: Item[]) {
  let index = 0

  function processChunk(deadline: IdleDeadline) {
    // Process items while we have idle time (aim for <50ms chunks)
    while (index < items.length && deadline.timeRemaining() > 0) {
      processItem(items[index])
      index++
    }

    // Schedule next chunk if more items remain
    if (index < items.length) {
      requestIdleCallback(processChunk)
    }
  }

  requestIdleCallback(processChunk)
}

With fallback for unsupported browsers:

const scheduleIdleWork = window.requestIdleCallback ?? ((cb: () => void) => setTimeout(cb, 1))

scheduleIdleWork(() => {
  // Non-critical work
})

When to use:

  • Analytics and telemetry
  • Saving state to localStorage/IndexedDB
  • Prefetching resources for likely next actions
  • Processing non-urgent data transformations
  • Lazy initialization of non-critical features

When NOT to use:

  • User-initiated actions that need immediate feedback
  • Rendering updates the user is waiting for
  • Time-sensitive operations