Key performance optimization patterns when writing React code.
Key rules by priority
🔴 CRITICAL: Eliminate waterfalls
// ❌ 순차 await — 각 요청이 이전을 기다림
const user = await getUser();
const posts = await getPosts();
// ✅ 병렬 — 독립 요청은 Promise.all
const [user, posts] = await Promise.all([getUser(), getPosts()]);
awaitmove to the actual usage branch (remove unnecessary waiting)- Stream content with Suspense boundaries
🔴 CRITICAL: Bundle size
// ❌ barrel import — 전체 모듈 로드
import { Button } from '@/components';
// ✅ 직접 import
import { Button } from '@/components/ui/Button';
next/dynamiclazy-load heavy components with- Load analytics/logging after hydration
- Improve perceived speed with preload on hover/focus
🟡 HIGH: Server-side
React.cache()deduplicate within requests with- Minimize data passed to the client
- Parallelize fetch by changing component structure
🟢 MEDIUM: Prevent re-renders
// ❌ 콜백에서만 쓰는 state를 구독
const [items, setItems] = useState([]);
const handleClick = () => process(items);
// ✅ ref로 전환 (리렌더 방지)
const itemsRef = useRef([]);
const handleClick = () => process(itemsRef.current);
- Split expensive work into memo components
useStatepass a function to the initial value (lazy init)startTransitionseparate non-urgent updates with- Compute derived state during render instead of in an effect
🔵 LOW: JS performance
- Repeated lookup →
Map/Setuse (O(1)) filter().map()→ combine into one loop- Create RegExp outside the loop
array.lengthcheck first, then expensive comparison
React in Remotion
Remotion video components are also React, so the same principles apply:
interpolate()is called every frame → cache if expensive- For heavy calculations,
useMemo/useCallback - Minimize rendering of offscreen elements