@kood/claude-code 0.3.11 → 0.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/index.js +30 -8
  2. package/package.json +4 -4
  3. package/templates/.claude/skills/nextjs-react-best-practices/AGENTS.md +663 -0
  4. package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +269 -0
  5. package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  6. package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-use-latest.md +49 -0
  7. package/templates/.claude/skills/nextjs-react-best-practices/rules/async-api-routes.md +38 -0
  8. package/templates/.claude/skills/nextjs-react-best-practices/rules/async-defer-await.md +80 -0
  9. package/templates/.claude/skills/nextjs-react-best-practices/rules/async-dependencies.md +36 -0
  10. package/templates/.claude/skills/nextjs-react-best-practices/rules/async-parallel.md +28 -0
  11. package/templates/.claude/skills/nextjs-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  12. package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  13. package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-conditional.md +31 -0
  14. package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  15. package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  16. package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-preload.md +50 -0
  17. package/templates/.claude/skills/nextjs-react-best-practices/rules/client-event-listeners.md +74 -0
  18. package/templates/.claude/skills/nextjs-react-best-practices/rules/client-swr-dedup.md +56 -0
  19. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-batch-dom-css.md +82 -0
  20. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-function-results.md +80 -0
  21. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-property-access.md +28 -0
  22. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-storage.md +70 -0
  23. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-combine-iterations.md +32 -0
  24. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-early-exit.md +50 -0
  25. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-hoist-regexp.md +45 -0
  26. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-index-maps.md +37 -0
  27. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-length-check-first.md +49 -0
  28. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-min-max-loop.md +82 -0
  29. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-set-map-lookups.md +24 -0
  30. package/templates/.claude/skills/nextjs-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  31. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-activity.md +26 -0
  32. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  33. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-conditional-render.md +40 -0
  34. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-content-visibility.md +38 -0
  35. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  36. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  37. package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-svg-precision.md +28 -0
  38. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-defer-reads.md +39 -0
  39. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-dependencies.md +45 -0
  40. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-derived-state.md +29 -0
  41. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  42. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  43. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-memo.md +44 -0
  44. package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-transitions.md +40 -0
  45. package/templates/.claude/skills/nextjs-react-best-practices/rules/server-after-nonblocking.md +73 -0
  46. package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-lru.md +41 -0
  47. package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-react.md +26 -0
  48. package/templates/.claude/skills/nextjs-react-best-practices/rules/server-parallel-fetching.md +79 -0
  49. package/templates/.claude/skills/nextjs-react-best-practices/rules/server-serialization.md +38 -0
  50. package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +751 -0
  51. package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +431 -0
  52. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-defer-await.md +80 -0
  53. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-dependencies.md +36 -0
  54. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-loader.md +44 -0
  55. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-parallel.md +28 -0
  56. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  57. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-conditional.md +31 -0
  58. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  59. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-lazy-routes.md +67 -0
  60. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-preload.md +50 -0
  61. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-event-listeners.md +74 -0
  62. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-tanstack-query.md +77 -0
  63. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-batch-dom-css.md +82 -0
  64. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-function-results.md +80 -0
  65. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-property-access.md +28 -0
  66. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-storage.md +70 -0
  67. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-combine-iterations.md +32 -0
  68. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-early-exit.md +50 -0
  69. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-hoist-regexp.md +45 -0
  70. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-index-maps.md +37 -0
  71. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-length-check-first.md +49 -0
  72. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-min-max-loop.md +82 -0
  73. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-set-map-lookups.md +24 -0
  74. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  75. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  76. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-conditional-render.md +40 -0
  77. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-content-visibility.md +38 -0
  78. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  79. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-svg-precision.md +28 -0
  80. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-defer-reads.md +39 -0
  81. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-dependencies.md +45 -0
  82. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-derived-state.md +29 -0
  83. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  84. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  85. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-memo.md +44 -0
  86. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-transitions.md +40 -0
  87. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-cache-lru.md +41 -0
  88. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +67 -0
  89. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-parallel-fetching.md +60 -0
  90. package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +38 -0
  91. package/templates/.claude/skills/vs-design-diverge/SKILL.md +307 -0
@@ -0,0 +1,663 @@
1
+ # Next.js React Best Practices
2
+
3
+ **Version 1.0.0**
4
+ Vercel Engineering
5
+ January 2026
6
+
7
+ > **Note:**
8
+ > This document is mainly for agents and LLMs to follow when maintaining,
9
+ > generating, or refactoring React and Next.js codebases. Humans
10
+ > may also find it useful, but guidance here is optimized for automation
11
+ > and consistency by AI-assisted workflows.
12
+
13
+ ---
14
+
15
+ <communication>
16
+
17
+ ## User Communication Protocol
18
+
19
+ **CRITICAL: Always communicate with the user in Korean (한국어).**
20
+
21
+ This applies to:
22
+ - Questions and clarifications
23
+ - Progress updates and summaries
24
+ - Explaining decisions and trade-offs
25
+ - Reporting errors or blockers
26
+
27
+ Internal processing and code comments remain in English. Only user-facing messages must be in Korean.
28
+
29
+ </communication>
30
+
31
+ ---
32
+
33
+ ## Abstract
34
+
35
+ Comprehensive performance optimization guide for React and Next.js applications, designed for AI agents and LLMs. Contains 40+ rules across 8 categories, prioritized by impact from critical (eliminating waterfalls, reducing bundle size) to incremental (advanced patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.
36
+
37
+ ---
38
+
39
+ <instructions>
40
+
41
+ ## Document Usage Instructions
42
+
43
+ @rules/async-defer-await.md
44
+ @rules/async-parallel.md
45
+ @rules/async-dependencies.md
46
+ @rules/async-api-routes.md
47
+ @rules/async-suspense-boundaries.md
48
+ @rules/bundle-barrel-imports.md
49
+ @rules/bundle-conditional.md
50
+ @rules/bundle-defer-third-party.md
51
+ @rules/bundle-dynamic-imports.md
52
+ @rules/bundle-preload.md
53
+ @rules/server-cache-react.md
54
+ @rules/server-cache-lru.md
55
+ @rules/server-serialization.md
56
+ @rules/server-parallel-fetching.md
57
+ @rules/server-after-nonblocking.md
58
+ @rules/client-event-listeners.md
59
+ @rules/client-swr-dedup.md
60
+ @rules/rerender-defer-reads.md
61
+ @rules/rerender-memo.md
62
+ @rules/rerender-dependencies.md
63
+ @rules/rerender-derived-state.md
64
+ @rules/rerender-functional-setstate.md
65
+ @rules/rerender-lazy-state-init.md
66
+ @rules/rerender-transitions.md
67
+ @rules/rendering-animate-svg-wrapper.md
68
+ @rules/rendering-content-visibility.md
69
+ @rules/rendering-hoist-jsx.md
70
+ @rules/rendering-svg-precision.md
71
+ @rules/rendering-hydration-no-flicker.md
72
+ @rules/rendering-activity.md
73
+ @rules/rendering-conditional-render.md
74
+ @rules/js-batch-dom-css.md
75
+ @rules/js-index-maps.md
76
+ @rules/js-cache-property-access.md
77
+ @rules/js-cache-function-results.md
78
+ @rules/js-cache-storage.md
79
+ @rules/js-combine-iterations.md
80
+ @rules/js-length-check-first.md
81
+ @rules/js-early-exit.md
82
+ @rules/js-hoist-regexp.md
83
+ @rules/js-min-max-loop.md
84
+ @rules/js-set-map-lookups.md
85
+ @rules/js-tosorted-immutable.md
86
+ @rules/advanced-event-handler-refs.md
87
+ @rules/advanced-use-latest.md
88
+
89
+ </instructions>
90
+
91
+ ---
92
+
93
+ <categories>
94
+
95
+ ## Categories by Priority
96
+
97
+ | Priority | Category | Impact | Description |
98
+ |----------|----------|--------|-------------|
99
+ | 1 | Eliminating Waterfalls | **CRITICAL** | Convert sequential awaits to parallel. Biggest gains |
100
+ | 2 | Bundle Size Optimization | **CRITICAL** | Improve TTI and LCP. Faster initial loads |
101
+ | 3 | Server-Side Performance | HIGH | Eliminate server-side waterfalls, reduce response times |
102
+ | 4 | Client-Side Data Fetching | MEDIUM-HIGH | Automatic deduplication, efficient data fetching |
103
+ | 5 | Re-render Optimization | MEDIUM | Minimize unnecessary re-renders, improve UI responsiveness |
104
+ | 6 | Rendering Performance | MEDIUM | Optimize browser rendering work |
105
+ | 7 | JavaScript Performance | LOW-MEDIUM | Hot path micro-optimizations |
106
+ | 8 | Advanced Patterns | LOW | Advanced implementation patterns for specific cases |
107
+
108
+ </categories>
109
+
110
+ ---
111
+
112
+ <critical_patterns>
113
+
114
+ ## 1. Eliminating Waterfalls (CRITICAL)
115
+
116
+ Waterfalls are the #1 performance killer. Each sequential await adds full network latency.
117
+
118
+ ### Parallel Execution
119
+
120
+ ```typescript
121
+ // ❌ Sequential execution (3 round trips)
122
+ const user = await fetchUser()
123
+ const posts = await fetchPosts()
124
+ const comments = await fetchComments()
125
+
126
+ // ✅ Parallel execution (1 round trip)
127
+ const [user, posts, comments] = await Promise.all([
128
+ fetchUser(),
129
+ fetchPosts(),
130
+ fetchComments()
131
+ ])
132
+ ```
133
+
134
+ ### Dependency-Based Parallelization
135
+
136
+ ```typescript
137
+ // ❌ profile waits for config unnecessarily
138
+ const [user, config] = await Promise.all([
139
+ fetchUser(),
140
+ fetchConfig()
141
+ ])
142
+ const profile = await fetchProfile(user.id)
143
+
144
+ // ✅ config and profile run in parallel with better-all
145
+ import { all } from 'better-all'
146
+
147
+ const { user, config, profile } = await all({
148
+ async user() { return fetchUser() },
149
+ async config() { return fetchConfig() },
150
+ async profile() {
151
+ return fetchProfile((await this.$.user).id)
152
+ }
153
+ })
154
+ ```
155
+
156
+ ### Suspense Boundaries
157
+
158
+ ```tsx
159
+ // ❌ Entire layout blocked by data fetching
160
+ async function Page() {
161
+ const data = await fetchData()
162
+ return (
163
+ <div>
164
+ <Sidebar />
165
+ <Header />
166
+ <DataDisplay data={data} />
167
+ <Footer />
168
+ </div>
169
+ )
170
+ }
171
+
172
+ // ✅ Wrapper shows immediately, data streams in
173
+ function Page() {
174
+ return (
175
+ <div>
176
+ <Sidebar />
177
+ <Header />
178
+ <Suspense fallback={<Skeleton />}>
179
+ <DataDisplay />
180
+ </Suspense>
181
+ <Footer />
182
+ </div>
183
+ )
184
+ }
185
+
186
+ async function DataDisplay() {
187
+ const data = await fetchData()
188
+ return <div>{data.content}</div>
189
+ }
190
+ ```
191
+
192
+ </critical_patterns>
193
+
194
+ ---
195
+
196
+ <bundle_optimization>
197
+
198
+ ## 2. Bundle Size Optimization (CRITICAL)
199
+
200
+ ### Avoid Barrel File Imports
201
+
202
+ ```tsx
203
+ // ❌ Import entire library (1583 modules, ~2.8s)
204
+ import { Check, X, Menu } from 'lucide-react'
205
+
206
+ // ✅ Direct imports (3 modules only)
207
+ import Check from 'lucide-react/dist/esm/icons/check'
208
+ import X from 'lucide-react/dist/esm/icons/x'
209
+ import Menu from 'lucide-react/dist/esm/icons/menu'
210
+
211
+ // ✅ Next.js 13.5+ auto-optimization
212
+ // next.config.js
213
+ module.exports = {
214
+ experimental: {
215
+ optimizePackageImports: ['lucide-react', '@mui/material']
216
+ }
217
+ }
218
+ ```
219
+
220
+ Affected libraries: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `@radix-ui/react-*`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`
221
+
222
+ ### Dynamic Imports
223
+
224
+ ```tsx
225
+ // ❌ Monaco bundled with main chunk (~300KB)
226
+ import { MonacoEditor } from './monaco-editor'
227
+
228
+ function CodePanel({ code }: { code: string }) {
229
+ return <MonacoEditor value={code} />
230
+ }
231
+
232
+ // ✅ Monaco loads on demand
233
+ import dynamic from 'next/dynamic'
234
+
235
+ const MonacoEditor = dynamic(
236
+ () => import('./monaco-editor').then(m => m.MonacoEditor),
237
+ { ssr: false }
238
+ )
239
+
240
+ function CodePanel({ code }: { code: string }) {
241
+ return <MonacoEditor value={code} />
242
+ }
243
+ ```
244
+
245
+ </bundle_optimization>
246
+
247
+ ---
248
+
249
+ <server_performance>
250
+
251
+ ## 3. Server-Side Performance (HIGH)
252
+
253
+ ### React.cache() - Per-Request Deduplication
254
+
255
+ ```typescript
256
+ import { cache } from 'react'
257
+
258
+ export const getCurrentUser = cache(async () => {
259
+ const session = await auth()
260
+ if (!session?.user?.id) return null
261
+ return await db.user.findUnique({ where: { id: session.user.id } })
262
+ })
263
+
264
+ // Within single request, multiple calls execute query only once
265
+ ```
266
+
267
+ ### LRU Cache - Cross-Request Caching
268
+
269
+ ```typescript
270
+ import { LRUCache } from 'lru-cache'
271
+
272
+ const cache = new LRUCache<string, any>({
273
+ max: 1000,
274
+ ttl: 5 * 60 * 1000 // 5 minutes
275
+ })
276
+
277
+ export async function getUser(id: string) {
278
+ const cached = cache.get(id)
279
+ if (cached) return cached
280
+
281
+ const user = await db.user.findUnique({ where: { id } })
282
+ cache.set(id, user)
283
+ return user
284
+ }
285
+
286
+ // Request 1: DB query, result cached
287
+ // Request 2: cache hit, no DB query
288
+ ```
289
+
290
+ ### Minimize Serialization at RSC Boundaries
291
+
292
+ ```tsx
293
+ // ❌ Serializes all 50 fields
294
+ async function Page() {
295
+ const user = await fetchUser() // 50 fields
296
+ return <Profile user={user} />
297
+ }
298
+
299
+ 'use client'
300
+ function Profile({ user }: { user: User }) {
301
+ return <div>{user.name}</div> // uses 1 field
302
+ }
303
+
304
+ // ✅ Serializes only 1 field
305
+ async function Page() {
306
+ const user = await fetchUser()
307
+ return <Profile name={user.name} />
308
+ }
309
+
310
+ 'use client'
311
+ function Profile({ name }: { name: string }) {
312
+ return <div>{name}</div>
313
+ }
314
+ ```
315
+
316
+ ### after() for Non-Blocking Operations
317
+
318
+ ```tsx
319
+ import { after } from 'next/server'
320
+
321
+ export async function POST(request: Request) {
322
+ await updateDatabase(request)
323
+
324
+ // Log after response is sent
325
+ after(async () => {
326
+ const userAgent = (await headers()).get('user-agent') || 'unknown'
327
+ logUserAction({ userAgent })
328
+ })
329
+
330
+ return new Response(JSON.stringify({ status: 'success' }), {
331
+ status: 200,
332
+ headers: { 'Content-Type': 'application/json' }
333
+ })
334
+ }
335
+ ```
336
+
337
+ </server_performance>
338
+
339
+ ---
340
+
341
+ <client_data_fetching>
342
+
343
+ ## 4. Client-Side Data Fetching (MEDIUM-HIGH)
344
+
345
+ ### SWR for Automatic Deduplication
346
+
347
+ ```tsx
348
+ import useSWR from 'swr'
349
+
350
+ // ❌ No deduplication, each instance fetches
351
+ function UserList() {
352
+ const [users, setUsers] = useState([])
353
+ useEffect(() => {
354
+ fetch('/api/users')
355
+ .then(r => r.json())
356
+ .then(setUsers)
357
+ }, [])
358
+ }
359
+
360
+ // ✅ Multiple instances share one request
361
+ function UserList() {
362
+ const { data: users } = useSWR('/api/users', fetcher)
363
+ }
364
+ ```
365
+
366
+ </client_data_fetching>
367
+
368
+ ---
369
+
370
+ <rerender_optimization>
371
+
372
+ ## 5. Re-render Optimization (MEDIUM)
373
+
374
+ ### Functional setState
375
+
376
+ ```tsx
377
+ // ❌ items as dependency, recreated every time
378
+ function TodoList() {
379
+ const [items, setItems] = useState(initialItems)
380
+
381
+ const addItems = useCallback((newItems: Item[]) => {
382
+ setItems([...items, ...newItems])
383
+ }, [items]) // Recreated on items change
384
+ }
385
+
386
+ // ✅ Stable callback, never recreated
387
+ function TodoList() {
388
+ const [items, setItems] = useState(initialItems)
389
+
390
+ const addItems = useCallback((newItems: Item[]) => {
391
+ setItems(curr => [...curr, ...newItems])
392
+ }, []) // No dependencies, always uses latest state
393
+ }
394
+ ```
395
+
396
+ ### Lazy State Initialization
397
+
398
+ ```tsx
399
+ // ❌ Runs on every render
400
+ function FilteredList({ items }: { items: Item[] }) {
401
+ const [searchIndex, setSearchIndex] = useState(buildSearchIndex(items))
402
+ const [query, setQuery] = useState('')
403
+ }
404
+
405
+ // ✅ Runs only on initial render
406
+ function FilteredList({ items }: { items: Item[] }) {
407
+ const [searchIndex, setSearchIndex] = useState(() => buildSearchIndex(items))
408
+ const [query, setQuery] = useState('')
409
+ }
410
+ ```
411
+
412
+ ### Subscribe to Derived State
413
+
414
+ ```tsx
415
+ // ❌ Re-renders on every pixel change
416
+ function Sidebar() {
417
+ const width = useWindowWidth() // continuous updates
418
+ const isMobile = width < 768
419
+ return <nav className={isMobile ? 'mobile' : 'desktop'}>
420
+ }
421
+
422
+ // ✅ Re-renders only when boolean changes
423
+ function Sidebar() {
424
+ const isMobile = useMediaQuery('(max-width: 767px)')
425
+ return <nav className={isMobile ? 'mobile' : 'desktop'}>
426
+ }
427
+ ```
428
+
429
+ </rerender_optimization>
430
+
431
+ ---
432
+
433
+ <rendering_performance>
434
+
435
+ ## 6. Rendering Performance (MEDIUM)
436
+
437
+ ### Animate SVG Wrapper
438
+
439
+ ```tsx
440
+ // ❌ Animating SVG directly - no hardware acceleration
441
+ function LoadingSpinner() {
442
+ return (
443
+ <svg className="animate-spin" width="24" height="24">
444
+ <circle cx="12" cy="12" r="10" />
445
+ </svg>
446
+ )
447
+ }
448
+
449
+ // ✅ Animating wrapper div - hardware accelerated
450
+ function LoadingSpinner() {
451
+ return (
452
+ <div className="animate-spin">
453
+ <svg width="24" height="24">
454
+ <circle cx="12" cy="12" r="10" />
455
+ </svg>
456
+ </div>
457
+ )
458
+ }
459
+ ```
460
+
461
+ ### content-visibility
462
+
463
+ ```css
464
+ /* Long list optimization */
465
+ .message-item {
466
+ content-visibility: auto;
467
+ contain-intrinsic-size: 0 80px;
468
+ }
469
+ ```
470
+
471
+ ```tsx
472
+ function MessageList({ messages }: { messages: Message[] }) {
473
+ return (
474
+ <div className="overflow-y-auto h-screen">
475
+ {messages.map(msg => (
476
+ <div key={msg.id} className="message-item">
477
+ <Avatar user={msg.author} />
478
+ <div>{msg.content}</div>
479
+ </div>
480
+ ))}
481
+ </div>
482
+ )
483
+ }
484
+ ```
485
+
486
+ For 1000 messages, browser skips layout/paint for ~990 off-screen items (10× faster initial render)
487
+
488
+ ### Prevent Hydration Mismatch
489
+
490
+ ```tsx
491
+ // ❌ SSR failure
492
+ function ThemeWrapper({ children }: { children: ReactNode }) {
493
+ const theme = localStorage.getItem('theme') || 'light' // localStorage undefined on server
494
+ return <div className={theme}>{children}</div>
495
+ }
496
+
497
+ // ❌ Flickering
498
+ function ThemeWrapper({ children }: { children: ReactNode }) {
499
+ const [theme, setTheme] = useState('light')
500
+
501
+ useEffect(() => {
502
+ const stored = localStorage.getItem('theme')
503
+ if (stored) setTheme(stored) // Runs after hydration → flicker
504
+ }, [])
505
+
506
+ return <div className={theme}>{children}</div>
507
+ }
508
+
509
+ // ✅ No flicker, no hydration mismatch
510
+ function ThemeWrapper({ children }: { children: ReactNode }) {
511
+ return (
512
+ <>
513
+ <div id="theme-wrapper">{children}</div>
514
+ <script
515
+ dangerouslySetInnerHTML={{
516
+ __html: `
517
+ (function() {
518
+ try {
519
+ var theme = localStorage.getItem('theme') || 'light';
520
+ var el = document.getElementById('theme-wrapper');
521
+ if (el) el.className = theme;
522
+ } catch (e) {}
523
+ })();
524
+ `,
525
+ }}
526
+ />
527
+ </>
528
+ )
529
+ }
530
+ ```
531
+
532
+ </rendering_performance>
533
+
534
+ ---
535
+
536
+ <javascript_performance>
537
+
538
+ ## 7. JavaScript Performance (LOW-MEDIUM)
539
+
540
+ ### Build Index Maps for Repeated Lookups
541
+
542
+ ```typescript
543
+ // ❌ O(n) per lookup
544
+ function processOrders(orders: Order[], users: User[]) {
545
+ return orders.map(order => ({
546
+ ...order,
547
+ user: users.find(u => u.id === order.userId)
548
+ }))
549
+ }
550
+
551
+ // ✅ O(1) per lookup
552
+ function processOrders(orders: Order[], users: User[]) {
553
+ const userById = new Map(users.map(u => [u.id, u]))
554
+ return orders.map(order => ({
555
+ ...order,
556
+ user: userById.get(order.userId)
557
+ }))
558
+ }
559
+ ```
560
+
561
+ 1000 orders × 1000 users: 1M ops → 2K ops
562
+
563
+ ### Early Length Check for Array Comparisons
564
+
565
+ ```typescript
566
+ // ❌ Always runs expensive comparison
567
+ function hasChanges(current: string[], original: string[]) {
568
+ return current.sort().join() !== original.sort().join()
569
+ }
570
+
571
+ // ✅ O(1) length check first
572
+ function hasChanges(current: string[], original: string[]) {
573
+ if (current.length !== original.length) return true
574
+
575
+ const currentSorted = current.toSorted()
576
+ const originalSorted = original.toSorted()
577
+ for (let i = 0; i < currentSorted.length; i++) {
578
+ if (currentSorted[i] !== originalSorted[i]) return true
579
+ }
580
+ return false
581
+ }
582
+ ```
583
+
584
+ ### Use toSorted() for Immutability
585
+
586
+ ```typescript
587
+ // ❌ Mutates original array
588
+ function UserList({ users }: { users: User[] }) {
589
+ const sorted = useMemo(
590
+ () => users.sort((a, b) => a.name.localeCompare(b.name)),
591
+ [users]
592
+ )
593
+ }
594
+
595
+ // ✅ Creates new array
596
+ function UserList({ users }: { users: User[] }) {
597
+ const sorted = useMemo(
598
+ () => users.toSorted((a, b) => a.name.localeCompare(b.name)),
599
+ [users]
600
+ )
601
+ }
602
+ ```
603
+
604
+ </javascript_performance>
605
+
606
+ ---
607
+
608
+ <advanced_patterns>
609
+
610
+ ## 8. Advanced Patterns (LOW)
611
+
612
+ ### useLatest for Stable Callback Refs
613
+
614
+ ```typescript
615
+ function useLatest<T>(value: T) {
616
+ const ref = useRef(value)
617
+ useEffect(() => {
618
+ ref.current = value
619
+ }, [value])
620
+ return ref
621
+ }
622
+ ```
623
+
624
+ ```tsx
625
+ // ❌ Effect re-runs on every callback change
626
+ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
627
+ const [query, setQuery] = useState('')
628
+
629
+ useEffect(() => {
630
+ const timeout = setTimeout(() => onSearch(query), 300)
631
+ return () => clearTimeout(timeout)
632
+ }, [query, onSearch])
633
+ }
634
+
635
+ // ✅ Stable effect, fresh callback
636
+ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
637
+ const [query, setQuery] = useState('')
638
+ const onSearchRef = useLatest(onSearch)
639
+
640
+ useEffect(() => {
641
+ const timeout = setTimeout(() => onSearchRef.current(query), 300)
642
+ return () => clearTimeout(timeout)
643
+ }, [query])
644
+ }
645
+ ```
646
+
647
+ </advanced_patterns>
648
+
649
+ ---
650
+
651
+ <references>
652
+
653
+ ## References
654
+
655
+ 1. [React](https://react.dev)
656
+ 2. [Next.js](https://nextjs.org)
657
+ 3. [SWR](https://swr.vercel.app)
658
+ 4. [better-all](https://github.com/shuding/better-all)
659
+ 5. [node-lru-cache](https://github.com/isaacs/node-lru-cache)
660
+ 6. [Next.js Package Import Optimization](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)
661
+ 7. [Vercel Dashboard Twice as Fast](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)
662
+
663
+ </references>