|
| 1 | +--- |
| 2 | +description: Vibe coding guidelines and architectural constraints for React Performance within the frontend domain. |
| 3 | +tags: [react, performance, use, react-compiler, best-practices, architecture, clean-code] |
| 4 | +topic: React Performance |
| 5 | +complexity: Architect |
| 6 | +last_evolution: 2026-03-22 |
| 7 | +vibe_coding_ready: true |
| 8 | +technology: React |
| 9 | +domain: frontend |
| 10 | +level: Senior/Architect |
| 11 | +version: "19+" |
| 12 | +ai_role: Senior React Performance Expert |
| 13 | +last_updated: 2026-03-22 |
| 14 | +--- |
| 15 | + |
| 16 | +# ⚡ React Performance & Best Practices |
| 17 | + |
| 18 | +[⬆️ Back to Top](#) |
| 19 | + |
| 20 | +# 📖 Context & Scope |
| 21 | +- **Primary Goal:** Outline advanced techniques for optimal performance in React 19+. |
| 22 | +- **Target Tooling:** Cursor, Windsurf, Antigravity. |
| 23 | +- **Tech Stack Version:** React 19+ |
| 24 | + |
| 25 | +## 📚 Topics |
| 26 | + |
| 27 | +### 1. Manual Memoization vs React Compiler |
| 28 | +**Context:** Avoiding unnecessary re-renders. |
| 29 | +#### ❌ Bad Practice |
| 30 | +```tsx |
| 31 | +import { useMemo, useCallback } from 'react'; |
| 32 | + |
| 33 | +function UserList({ users }) { |
| 34 | + const sortedUsers = useMemo(() => users.sort(), [users]); |
| 35 | + const handleSelect = useCallback((id) => selectUser(id), []); |
| 36 | + |
| 37 | + return ( |
| 38 | + <ul> |
| 39 | + {sortedUsers.map(u => <li key={u.id} onClick={() => handleSelect(u.id)}>{u.name}</li>)} |
| 40 | + </ul> |
| 41 | + ); |
| 42 | +} |
| 43 | +``` |
| 44 | +#### ⚠️ Problem |
| 45 | +Adding manual `useMemo` and `useCallback` clutters the codebase, introduces dependency array bugs, and makes code harder to refactor. |
| 46 | +#### ✅ Best Practice |
| 47 | +```tsx |
| 48 | +function UserList({ users }) { |
| 49 | + const sortedUsers = users.sort(); |
| 50 | + const handleSelect = (id) => selectUser(id); |
| 51 | + |
| 52 | + return ( |
| 53 | + <ul> |
| 54 | + {sortedUsers.map(u => <li key={u.id} onClick={() => handleSelect(u.id)}>{u.name}</li>)} |
| 55 | + </ul> |
| 56 | + ); |
| 57 | +} |
| 58 | +``` |
| 59 | +#### 🚀 Solution |
| 60 | +Rely on the **React Compiler** (introduced in React 19+). The compiler automatically memoizes values and functions, meaning manual hooks are largely obsolete and code becomes purely declarative. |
| 61 | +- **Performance Note:** The React Compiler analyzes your component structure and injects optimal memoization (similar to SolidJS's granular updates), eliminating the overhead of manual dependency tracking. |
| 62 | +- **Security Note:** While the React Compiler does not directly impact security, it ensures components render exactly when their inputs change, reducing side effects that might otherwise expose temporary or stale data to users. |
| 63 | + |
| 64 | +### 2. Resolving Promises During Render |
| 65 | +**Context:** Conditionally handling promises without `useEffect` or `useState`. |
| 66 | +#### ❌ Bad Practice |
| 67 | +```tsx |
| 68 | +import { useEffect, useState } from 'react'; |
| 69 | + |
| 70 | +function Profile({ profilePromise }) { |
| 71 | + const [data, setData] = useState(null); |
| 72 | + |
| 73 | + useEffect(() => { |
| 74 | + profilePromise.then(res => setData(res)); |
| 75 | + }, [profilePromise]); |
| 76 | + |
| 77 | + if (!data) return <p>Loading...</p>; |
| 78 | + return <div>{data.name}</div>; |
| 79 | +} |
| 80 | +``` |
| 81 | +#### ⚠️ Problem |
| 82 | +Using `useEffect` to unwrap promises leads to "waterfalls", unnecessary rendering cycles, and race conditions. |
| 83 | +#### ✅ Best Practice |
| 84 | +```tsx |
| 85 | +import { use, Suspense } from 'react'; |
| 86 | + |
| 87 | +function Profile({ profilePromise }) { |
| 88 | + const data = use(profilePromise); |
| 89 | + return <div>{data.name}</div>; |
| 90 | +} |
| 91 | + |
| 92 | +// Parent Usage |
| 93 | +// <Suspense fallback={<p>Loading...</p>}> |
| 94 | +// <Profile profilePromise={profilePromise} /> |
| 95 | +// </Suspense> |
| 96 | +``` |
| 97 | +#### 🚀 Solution |
| 98 | +Use the `use()` API inside components combined with `<Suspense>`. |
| 99 | +- **Performance Note:** `use()` suspends the component rendering if the promise is not resolved. This seamlessly integrates with `<Suspense>`, providing a highly optimized rendering fallback behavior. |
| 100 | +- **Security Note:** `use()` can also resolve context, mitigating prop-drilling vulnerabilities and ensuring components securely consume data directly from contexts they are explicitly authorized for. Always sanitize any text coming from external APIs before rendering. |
| 101 | + |
| 102 | +[⬆️ Back to Top](#) |
0 commit comments