返回 AiToEarn
js-request-idle-callback.md
根目录 / project / aitoearn-web / .agents / skills / vercel-react-best-practices / rules / js-request-idle-callback.md
1 ---
2 title: Defer Non-Critical Work with requestIdleCallback
3 impact: MEDIUM
4 impactDescription: keeps UI responsive during background tasks
5 tags: javascript, performance, idle, scheduling, analytics
6 ---
7
8 ## Defer Non-Critical Work with requestIdleCallback
9
10 **Impact: MEDIUM (keeps UI responsive during background tasks)**
11
12 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.
13
14 **Incorrect (blocks main thread during user interaction):**
15
16 ```typescript
17 function handleSearch(query: string) {
18 const results = searchItems(query)
19 setResults(results)
20
21 // These block the main thread immediately
22 analytics.track('search', { query })
23 saveToRecentSearches(query)
24 prefetchTopResults(results.slice(0, 3))
25 }
26 ```
27
28 **Correct (defers non-critical work to idle time):**
29
30 ```typescript
31 function handleSearch(query: string) {
32 const results = searchItems(query)
33 setResults(results)
34
35 // Defer non-critical work to idle periods
36 requestIdleCallback(() => {
37 analytics.track('search', { query })
38 })
39
40 requestIdleCallback(() => {
41 saveToRecentSearches(query)
42 })
43
44 requestIdleCallback(() => {
45 prefetchTopResults(results.slice(0, 3))
46 })
47 }
48 ```
49
50 **With timeout for required work:**
51
52 ```typescript
53 // Ensure analytics fires within 2 seconds even if browser stays busy
54 requestIdleCallback(
55 () => analytics.track('page_view', { path: location.pathname }),
56 { timeout: 2000 }
57 )
58 ```
59
60 **Chunking large tasks:**
61
62 ```typescript
63 function processLargeDataset(items: Item[]) {
64 let index = 0
65
66 function processChunk(deadline: IdleDeadline) {
67 // Process items while we have idle time (aim for <50ms chunks)
68 while (index < items.length && deadline.timeRemaining() > 0) {
69 processItem(items[index])
70 index++
71 }
72
73 // Schedule next chunk if more items remain
74 if (index < items.length) {
75 requestIdleCallback(processChunk)
76 }
77 }
78
79 requestIdleCallback(processChunk)
80 }
81 ```
82
83 **With fallback for unsupported browsers:**
84
85 ```typescript
86 const scheduleIdleWork = window.requestIdleCallback ?? ((cb: () => void) => setTimeout(cb, 1))
87
88 scheduleIdleWork(() => {
89 // Non-critical work
90 })
91 ```
92
93 **When to use:**
94
95 - Analytics and telemetry
96 - Saving state to localStorage/IndexedDB
97 - Prefetching resources for likely next actions
98 - Processing non-urgent data transformations
99 - Lazy initialization of non-critical features
100
101 **When NOT to use:**
102
103 - User-initiated actions that need immediate feedback
104 - Rendering updates the user is waiting for
105 - Time-sensitive operations
106
106 lines MARKDOWN