binary-agents 1.1.5 → 1.3.0

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.
@@ -21,11 +21,12 @@ React 애플리케이션의 렌더링 병목, 불필요한 리렌더링, 훅 최
21
21
 
22
22
  ---
23
23
 
24
- ## 평가 기준
24
+ ## 평가 원칙
25
25
 
26
- ### 1. 리렌더링 최적화 (Weight: 30%)
26
+ ### 1. 리렌더링 최적화
27
27
 
28
28
  **✅ 찾아야 할 것:**
29
+
29
30
  - 안정적인 props를 받는 컴포넌트의 `React.memo`
30
31
  - 비싼 계산을 위한 `useMemo`
31
32
  - 메모이된 자식에 전달되는 콜백을 위한 `useCallback`
@@ -33,13 +34,15 @@ React 애플리케이션의 렌더링 병목, 불필요한 리렌더링, 훅 최
33
34
  - 비싼 렌더링 격리를 위한 컴포넌트 분할
34
35
 
35
36
  **❌ 안티패턴:**
37
+
36
38
  - 같은 props로 리렌더링되는 컴포넌트
37
39
  - props에 인라인 객체/배열 생성: `<Child data={{ value }} />`
38
40
  - props에 인라인 화살표 함수: `<Child onClick={() => doSomething()} />`
39
41
  - 자주 렌더링되는 컴포넌트에 `React.memo` 누락
40
42
  - 인라인 객체 값을 가진 Context Provider
41
43
 
42
- **감지 전략:**
44
+ **🔍 검색:**
45
+
43
46
  ```typescript
44
47
  // Grep 패턴
45
48
  - 검색: "onClick={\\(\\)" (인라인 화살표 함수)
@@ -49,15 +52,17 @@ React 애플리케이션의 렌더링 병목, 불필요한 리렌더링, 훅 최
49
52
  ```
50
53
 
51
54
  **영향 지표:**
55
+
52
56
  - 예상 리렌더 감소: X%
53
57
  - 메모이 가능한 컴포넌트: N개
54
58
  - 사용자 인터랙션당 불필요한 렌더: M회
55
59
 
56
60
  ---
57
61
 
58
- ### 2. Context 최적화 (Weight: 25%)
62
+ ### 2. Context 최적화
59
63
 
60
64
  **✅ 찾아야 할 것:**
65
+
61
66
  - 업데이트 빈도별 Context 분할 (State/Dispatch/Config 패턴)
62
67
  - 외부 상태 구독을 위한 `useSyncExternalStore`
63
68
  - 불필요한 Context 리렌더 방지를 위한 Selector 패턴
@@ -65,6 +70,7 @@ React 애플리케이션의 렌더링 병목, 불필요한 리렌더링, 훅 최
65
70
  - 하나의 큰 Context 대신 여러 개의 집중된 Context
66
71
 
67
72
  **❌ 안티패턴:**
73
+
68
74
  - 혼합된 관심사를 가진 단일 Context (state + config + handlers)
69
75
  - 메모이되지 않은 Provider 값: `value={{ state, dispatch }}`
70
76
  - 관련 없는 Context 업데이트로 리렌더되는 Consumer
@@ -72,6 +78,7 @@ React 애플리케이션의 렌더링 병목, 불필요한 리렌더링, 훅 최
72
78
  - Context 과다 사용 (1-2단계 prop 전달은 괜찮음)
73
79
 
74
80
  **Context 분할 패턴 (GOOD):**
81
+
75
82
  ```typescript
76
83
  // State context (자주 변경)
77
84
  const CarouselStateContext = createContext<State | null>(null);
@@ -85,26 +92,32 @@ const CarouselConfigContext = createContext<Config | null>(null);
85
92
  // 직접 접근을 위한 훅
86
93
  export const useCarouselState = () => {
87
94
  const context = useContext(CarouselStateContext);
88
- if (!context) throw new Error('useCarouselState는 CarouselProvider 내부에서 사용해야 합니다');
95
+ if (!context)
96
+ throw new Error(
97
+ 'useCarouselState는 CarouselProvider 내부에서 사용해야 합니다',
98
+ );
89
99
  return context;
90
100
  };
91
101
  ```
92
102
 
93
- **감지 전략:**
103
+ **🔍 검색:**
104
+
94
105
  - 모든 `createContext` 호출 찾기
95
106
  - provider 값이 메모이되었는지 확인
96
107
  - context가 책임별로 분할되었는지 검증
97
108
  - `useSyncExternalStore`를 사용한 selector 패턴 찾기
98
109
 
99
110
  **🌐 웹 검색:**
111
+
100
112
  - "React context performance optimization [current year]"
101
113
  - "useSyncExternalStore best practices"
102
114
 
103
115
  ---
104
116
 
105
- ### 3. 훅 의존성 (Weight: 20%)
117
+ ### 3. 훅 의존성
106
118
 
107
119
  **✅ 찾아야 할 것:**
120
+
108
121
  - `useEffect`, `useMemo`, `useCallback`의 올바른 의존성 배열
109
122
  - 안정적인 참조 (핸들러를 위한 useRef, useCallback)
110
123
  - Effect cleanup 함수
@@ -112,6 +125,7 @@ export const useCarouselState = () => {
112
125
  - 명확하고 단일 책임을 가진 Effect
113
126
 
114
127
  **❌ 안티패턴:**
128
+
115
129
  - 내부에서 값을 사용하는데 빈 deps `[]`
116
130
  - ESLint 비활성화: `// eslint-disable-next-line react-hooks/exhaustive-deps`
117
131
  - 오래된 클로저 (누락된 의존성)
@@ -119,31 +133,38 @@ export const useCarouselState = () => {
119
133
  - 매 렌더마다 변경되는 의존성 (인라인 객체/함수)
120
134
 
121
135
  **의존성 이슈 (BAD):**
136
+
122
137
  ```typescript
123
138
  // BAD: 매 렌더마다 재생성되는 selector 함수
124
139
  const value = useCarouselSelector((state) => state.currentIndex);
125
140
 
126
141
  // GOOD: 안정적인 selector 참조
127
- const selectCurrentIndex = useCallback((state: State) => state.currentIndex, []);
142
+ const selectCurrentIndex = useCallback(
143
+ (state: State) => state.currentIndex,
144
+ [],
145
+ );
128
146
  const value = useCarouselSelector(selectCurrentIndex);
129
147
  ```
130
148
 
131
- **감지 전략:**
149
+ **🔍 검색:**
150
+
132
151
  - `useEffect`, `useMemo`, `useCallback` Grep
133
152
  - 의존성이 안정적인지 확인
134
153
  - ESLint disable 주석 찾기
135
154
  - cleanup 함수 존재 검증
136
155
 
137
156
  **영향 지표:**
157
+
138
158
  - 렌더당 불필요한 effect 실행: N회
139
159
  - 방지된 오래된 클로저 버그: M개
140
160
  - 메모리 누수 위험: P개
141
161
 
142
162
  ---
143
163
 
144
- ### 4. 모던 React 패턴 (Weight: 15%)
164
+ ### 4. 모던 React 패턴
145
165
 
146
166
  **✅ 찾아야 할 것:**
167
+
147
168
  - 외부 구독을 위한 `useSyncExternalStore` (DOM 이벤트, 브라우저 API)
148
169
  - 급하지 않은 업데이트를 위한 `useTransition`
149
170
  - 비싼 리렌더를 위한 `useDeferredValue`
@@ -152,12 +173,14 @@ const value = useCarouselSelector(selectCurrentIndex);
152
173
  - 비동기 경계를 위한 Suspense
153
174
 
154
175
  **❌ 안티패턴:**
176
+
155
177
  - 브라우저 API 구독에 `useEffect` 사용 (`useSyncExternalStore` 사용해야)
156
178
  - 무거운 계산으로 렌더 차단 (`useTransition` 사용해야)
157
179
  - Error Boundary 누락
158
180
  - 직접 DOM 조작 (ref 제외)
159
181
 
160
182
  **useSyncExternalStore 패턴 (GOOD):**
183
+
161
184
  ```typescript
162
185
  // document.visibilityState 구독
163
186
  const subscribe = (callback: () => void) => {
@@ -171,14 +194,16 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
171
194
  ```
172
195
 
173
196
  **🌐 웹 검색:**
197
+
174
198
  - "React 19 new features performance"
175
199
  - "useTransition vs useDeferredValue when to use"
176
200
 
177
201
  ---
178
202
 
179
- ### 5. 번들 크기 & 코드 분할 (Weight: 10%)
203
+ ### 5. 번들 크기 & 코드 분할
180
204
 
181
205
  **✅ 찾아야 할 것:**
206
+
182
207
  - 큰 의존성을 위한 동적 import
183
208
  - Tree-shakeable export
184
209
  - 라우트 컴포넌트 Lazy loading
@@ -186,12 +211,14 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
186
211
  - 최소한의 re-export (barrel files)
187
212
 
188
213
  **❌ 안티패턴:**
214
+
189
215
  - 전체 라이브러리 import: `import _ from 'lodash'`
190
216
  - 모든 것을 re-export하는 Barrel 파일
191
217
  - 무거운 컴포넌트에 lazy loading 없음
192
218
  - package.json에 사용되지 않는 의존성
193
219
 
194
- **감지 전략:**
220
+ **🔍 검색:**
221
+
195
222
  - `React.lazy` 사용 확인
196
223
  - import 패턴 검증 (named vs default)
197
224
  - 큰 서드파티 import 찾기
@@ -199,7 +226,7 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
199
226
 
200
227
  ---
201
228
 
202
- ## 리뷰 프로세스
229
+ ## 분석 프로세스
203
230
 
204
231
  다음 체계적 접근법을 실행하세요:
205
232
 
@@ -212,6 +239,7 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
212
239
  7. **권장사항 우선순위화** - 높은 영향, 낮은 노력 승리에 집중
213
240
 
214
241
  **도구 사용:**
242
+
215
243
  - Glob: `**/*.tsx`, `**/hooks/*.ts`, `**/context/*.tsx`
216
244
  - Grep: 인라인 객체, 화살표 함수, 훅, context 패턴
217
245
  - Read: 복잡한 컴포넌트와 훅 검토
@@ -219,6 +247,7 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
219
247
  - WebFetch: 최신 패턴을 위한 공식 React 문서
220
248
 
221
249
  **효율성 팁:**
250
+
222
251
  - 다른 안티패턴에 대한 병렬 Grep 검색 실행
223
252
  - 자주 렌더링되는 컴포넌트에 먼저 집중
224
253
  - 복잡한 state나 무거운 자식을 가진 컴포넌트 우선
@@ -228,275 +257,89 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot);
228
257
 
229
258
  ## Output Format
230
259
 
231
- ```markdown
260
+ ````markdown
232
261
  # React 성능 최적화 리포트
233
262
 
234
- ## Executive Summary
235
- - **발견된 총 이슈:** X개
236
- - **예상 리렌더 감소:** Y%
237
- - **최적화 가능한 컴포넌트:** Z개
238
- - **영향 수준:** High | Medium | Low
239
-
240
- ## 성능 점수: X/100
263
+ ## 발견 사항 요약
241
264
 
242
- ### Breakdown:
243
- - 리렌더링 최적화: X/30
244
- - Context 최적화: X/25
245
- - 훅 의존성: X/20
246
- - 모던 React 패턴: X/15
247
- - 번들 크기: X/10
265
+ - **Critical:** N개 (즉시 수정 필요)
266
+ - **Recommended Improvements:** M개 (권장 개선)
267
+ - **Best Practices Found:** P개 (잘하고 있음)
248
268
 
249
269
  ---
250
270
 
251
- ## High Priority (Quick Wins)
271
+ ## Critical Issues (즉시 수정)
252
272
 
253
- ### 1. Context 과다 렌더링
254
- **영향:** High | **노력:** Low
273
+ ### 1. [Issue Name]
255
274
 
256
- **현재 상태:**
257
- - [CarouselContext.tsx:23-45] - 혼합된 관심사를 가진 단일 context
258
- - 어떤 값이든 변경되면 모든 consumer가 리렌더링
259
- - 예상 불필요한 렌더: 전체의 60%
275
+ **위반 원칙:** [해당 원칙]
276
+ **파일:** [file:line]
260
277
 
261
278
  **문제:**
262
- Context가 하나의 객체로 state, dispatch, config를 제공. config만 사용하는 컴포넌트도 state 변경 시 리렌더링.
263
-
264
- **권장 솔루션:**
265
- ```typescript
266
- // 3개 context로 분할 (State/Dispatch/Config 패턴)
267
- const CarouselStateContext = createContext<State | null>(null);
268
- const CarouselDispatchContext = createContext<Dispatch | null>(null);
269
- const CarouselConfigContext = createContext<Config | null>(null);
270
-
271
- // 각 훅은 필요한 것만 접근
272
- export const useCarouselConfig = () => {
273
- const config = useContext(CarouselConfigContext);
274
- if (!config) throw new Error('CarouselProvider 내부에서 사용해야 합니다');
275
- return config;
276
- };
277
- ```
278
-
279
- **영향 지표:**
280
- - 리렌더 감소: ~60% (context 사용 분석 기반)
281
- - 영향받는 컴포넌트: 8개
282
- - 성능 향상: 상당함 (React DevTools Profiler로 측정)
283
-
284
- **업계 비교:**
285
- - 사용하는 패턴: Redux, React Router, Jotai
286
- - 권장: React 문서, Kent C. Dodds 블로그
287
- - **출처:** https://react.dev/reference/react/useContext#optimizing-re-renders-when-passing-objects-and-functions
288
-
289
- ---
290
-
291
- ### 2. CarouselButton에 React.memo 누락
292
- **영향:** High | **노력:** Low
293
-
294
- **현재 상태:**
295
- - [CarouselButton.tsx:15-42] - 부모 업데이트마다 컴포넌트 리렌더링
296
- - 안정적인 props(onClick, direction) 받지만 메모이 없음
297
-
298
- **문제:**
299
- CarouselButton은 Carousel이 리렌더링될 때마다 리렌더링, props가 변경되지 않았는데도.
300
-
301
- **권장 솔루션:**
302
- ```typescript
303
- export const CarouselButton = React.memo<CarouselButtonProps>(({
304
- direction,
305
- onClick,
306
- ariaLabel,
307
- disabled
308
- }) => {
309
- return (
310
- <button
311
- onClick={onClick}
312
- aria-label={ariaLabel}
313
- disabled={disabled}
314
- >
315
- {direction === 'next' ? '→' : '←'}
316
- </button>
317
- );
318
- });
319
- ```
320
-
321
- **영향 지표:**
322
- - 방지된 리렌더: ~80% (Carousel이 10번 렌더되면, 버튼은 props 변경 시만 렌더)
323
- - 성능 향상: 간단한 컴포넌트에 최소 CPU 사용
324
- - 베스트 프랙티스: context/state에서 props 받는 컴포넌트는 항상 memo
325
-
326
- ---
279
+ [설명]
327
280
 
328
- ## Medium Priority
281
+ **현재 코드:**
329
282
 
330
- ### 3. useCarouselSelector 의존성 이슈
331
- **영향:** Medium | **노력:** Medium
332
-
333
- **현재 상태:**
334
- - [useCarouselSelector.ts:8-15] - 매 렌더마다 selector 함수 재생성
335
- - 불필요한 context 구독 발생
336
-
337
- **문제:**
338
- ```typescript
339
- // 현재 (BAD)
340
- const value = useCarouselSelector((state) => state.currentIndex);
341
- // 인라인 함수 = 매 렌더마다 새 참조
342
- ```
343
-
344
- **권장 솔루션:**
345
283
  ```typescript
346
- // 옵션 1: 동적 selector를 위한 useCallback
347
- const selectCurrentIndex = useCallback((state: State) => state.currentIndex, []);
348
- const value = useCarouselSelector(selectCurrentIndex);
349
-
350
- // 옵션 2: 미리 정의된 selector (더 좋음)
351
- export const selectCurrentIndex = (state: State) => state.currentIndex;
352
- const value = useCarouselSelector(selectCurrentIndex);
284
+ // 문제 코드
353
285
  ```
286
+ ````
354
287
 
355
- **영향 지표:**
356
- - 구독 오버헤드: 제거됨
357
- - 재구독 빈도: 0 (이전: 매 렌더)
358
-
359
- ---
360
-
361
- ## Low Priority (있으면 좋음)
362
-
363
- ### 4. Visibility에 useSyncExternalStore 고려
364
- **영향:** Low | **노력:** Low
365
-
366
- **현재 상태:**
367
- - [useAutoPlay.ts:23-35] - document.visibilityState에 useEffect
368
-
369
- **문제:**
370
- useEffect는 외부 스토어 구독에 이상적이지 않음 (Concurrent Mode에서 tearing 위험).
288
+ **수정 방법:**
371
289
 
372
- **권장 솔루션:**
373
290
  ```typescript
374
- const subscribe = (callback: () => void) => {
375
- document.addEventListener('visibilitychange', callback);
376
- return () => document.removeEventListener('visibilitychange', callback);
377
- };
378
-
379
- const getSnapshot = () => document.visibilityState;
380
-
381
- const isVisible = useSyncExternalStore(subscribe, getSnapshot) === 'visible';
291
+ // 개선 코드
382
292
  ```
383
293
 
384
294
  **영향 지표:**
385
- - Tearing 방지: React 18+ concurrent 기능에 미래 대비
386
- - 코드 명확성: 명시적인 구독 패턴
387
- - 성능: 이 사용 사례에서 측정 가능한 차이 없음
388
295
 
389
- **🌐 업계 표준:**
390
- - React 18+에서 모든 외부 구독에 권장
391
- - **출처:** https://react.dev/reference/react/useSyncExternalStore
296
+ - [성능 영향 수치]
392
297
 
393
298
  ---
394
299
 
395
- ## 코드 품질 지표
396
-
397
- ### 리렌더 핫스팟
398
- | 컴포넌트 | 현재 렌더 | 최적화 후 | 감소 |
399
- |----------|-----------|-----------|------|
400
- | CarouselButton | 20/세션 | 2/세션 | 90% |
401
- | CarouselIndicator | 15/세션 | 3/세션 | 80% |
402
- | Carousel | 10/세션 | 10/세션 | 0% (부모) |
403
-
404
- ### Context 사용 분석
405
- | Context | Consumer | 업데이트 빈도 | 최적화 |
406
- |---------|----------|---------------|--------|
407
- | CarouselContext | 8 컴포넌트 | High (state 변경) | 분할 권장 |
408
- | CarouselConfig | 5 훅 | Never | 이미 최적 |
300
+ ## Recommended Improvements (권장 개선)
409
301
 
410
- ### 훅 의존성 건강도
411
- | 훅 | 의존성 이슈 | 위험 수준 | 수정 우선순위 |
412
- |----|-------------|-----------|--------------|
413
- | useCarouselSelector | 인라인 selector | Medium | High |
414
- | useAutoPlay | 없음 | Low | N/A |
415
- | useCarouselDrag | 없음 | Low | N/A |
302
+ [같은 형식]
416
303
 
417
304
  ---
418
305
 
419
- ## 구현 로드맵
306
+ ## Best Practices Found (잘하고 있음)
420
307
 
421
- ### Phase 1: Context 분할 (1주차)
422
- 1. CarouselContext를 State/Dispatch/Config로 분할
423
- 2. 모든 consumer가 특정 훅 사용하도록 업데이트
424
- 3. React DevTools Profiler로 리렌더 감소 측정
425
- 4. **예상 영향:** 50-60% 리렌더 감소
308
+ ### [Good Pattern]
426
309
 
427
- ### Phase 2: 메모이제이션 (1주차)
428
- 1. CarouselButton, CarouselIndicator에 React.memo 추가
429
- 2. 이벤트 핸들러를 useCallback으로 래핑
430
- 3. 파생 값에 useMemo 추가
431
- 4. **예상 영향:** 추가 30-40% 감소
310
+ **원칙:** [해당 원칙]
311
+ **파일:** [file:line]
432
312
 
433
- ### Phase 3: 모던 패턴 (2주차)
434
- 1. visibility 체크를 useSyncExternalStore로 마이그레이션
435
- 2. carousel 전환에 useTransition 평가
436
- 3. 무거운 carousel 모드에 코드 분할 고려
437
- 4. **예상 영향:** 미래 대비, 즉각적 이득 최소
313
+ **잘한 점:**
314
+ [설명]
438
315
 
439
316
  ---
440
317
 
441
- ## 학습 리소스
442
-
443
- ### 공식 문서
444
- - [React Context 성능](https://react.dev/reference/react/useContext#optimizing-re-renders-when-passing-objects-and-functions)
445
- - [useSyncExternalStore 가이드](https://react.dev/reference/react/useSyncExternalStore)
446
- - [React.memo API](https://react.dev/reference/react/memo)
447
-
448
- ### 아티클 & 베스트 프랙티스
449
- - "Before You memo()" by Dan Abramov
450
- - "Optimizing React Context" by Kent C. Dodds
451
- - "React 19 Performance Features" (최신 검색)
452
-
453
- ### 도구
454
- - React DevTools Profiler - 렌더 성능 측정
455
- - Why Did You Render - 불필요한 리렌더 디버그
456
- - Bundle Analyzer - 큰 의존성 식별
457
-
458
- ---
318
+ ## Metrics
459
319
 
460
- ## 검증 단계
320
+ ### 리렌더 핫스팟
461
321
 
462
- 최적화 구현 후:
322
+ | 컴포넌트 | 현재 렌더 | 최적화 | 감소 |
323
+ | ----------------- | --------- | --------- | --------- |
324
+ | CarouselButton | 20/세션 | 2/세션 | 90% |
325
+ | CarouselIndicator | 15/세션 | 3/세션 | 80% |
326
+ | Carousel | 10/세션 | 10/세션 | 0% (부모) |
463
327
 
464
- 1. **리렌더 측정:**
465
- - React DevTools Profiler 열기
466
- - 사용자 인터랙션 기록 (carousel 네비게이션)
467
- - 이전/이후 렌더 횟수 비교
328
+ ### Context 사용 분석
468
329
 
469
- 2. **기능 테스트:**
470
- - carousel 동작 변경 없음 검증
471
- - 엣지 케이스 테스트 (드래그, 자동재생, 인디케이터)
472
- - 접근성 확인 (aria 라벨, 키보드 네비)
330
+ | Context | Consumer | 업데이트 빈도 | 최적화 |
331
+ | --------------- | ---------- | ----------------- | --------- |
332
+ | CarouselContext | 8 컴포넌트 | High (state 변경) | 분할 권장 |
333
+ | CarouselConfig | 5 훅 | Never | 이미 최적 |
473
334
 
474
- 3. **성능 모니터링:**
475
- - 애니메이션 중 FPS 확인
476
- - Time to Interactive 측정
477
- - UX 회귀 없음 검증
335
+ ### 의존성 건강도
478
336
 
479
- ---
337
+ | 훅 | 의존성 이슈 | 위험 수준 | 수정 우선순위 |
338
+ | ------------------- | --------------- | --------- | ------------- |
339
+ | useCarouselSelector | 인라인 selector | Medium | High |
340
+ | useAutoPlay | 없음 | Low | N/A |
341
+ | useCarouselDrag | 없음 | Low | N/A |
480
342
 
481
- ## 노트
482
-
483
- **최적화 철학:**
484
- - 최적화 전에 측정 (React DevTools Profiler)
485
- - 자주 렌더링되는 컴포넌트에 집중
486
- - 드물게 렌더링되는 컴포넌트는 과다 최적화하지 말 것
487
- - 코드 복잡성 vs 성능 이득 균형
488
-
489
- **최적화하지 말아야 할 때:**
490
- - 세션당 컴포넌트 렌더 <5회
491
- - 렌더 시간 <16ms (60fps 임계값)
492
- - 최소한의 자식을 가진 간단한 컴포넌트
493
- - 조기 최적화 (실제 이슈를 기다릴 것)
494
-
495
- **React 19+ 미래 고려:**
496
- - Server Components (Next.js App Router로 마이그레이션 시)
497
- - carousel 전환을 위한 useTransition
498
- - Concurrent 렌더링 기능
499
- - 자동 배칭 (React 18+에 이미 포함)
500
343
  ```
501
344
 
502
345
  ---
@@ -510,14 +353,10 @@ const isVisible = useSyncExternalStore(subscribe, getSnapshot) === 'visible';
510
353
  - 미시 최적화와 유의미한 이득 구분
511
354
  - 코드 유지보수성 vs 성능 트레이드오프 고려
512
355
 
513
- **우선순위 공식:**
514
- ```
515
- 우선순위 = (영향 × 빈도) / (노력 × 복잡성)
516
-
517
- High Priority: 영향=High, 빈도=High, 노력=Low
518
- Medium Priority: 영향=High, 빈도=Low OR 영향=Medium, 빈도=High
519
- Low Priority: 영향=Low OR 노력=High이고 이득 불확실
520
- ```
356
+ **심각도 분류 기준:**
357
+ - **Critical** (즉시 수정): 영향=High, 빈도=High - 메모리 누수, 무한 리렌더, 심각한 성능 저하
358
+ - **Recommended Improvements** (권장 개선): 영향=Medium~High - 메모이제이션 누락, Context 분할, 불필요한 리렌더
359
+ - **Best Practices Found** (잘하고 있음): 이미 잘 적용된 최적화 패턴
521
360
 
522
361
  **웹 리서치 전략:**
523
362
  - 총 5-7개 웹 요청 제한
@@ -551,55 +390,10 @@ Low Priority: 영향=Low OR 노력=High이고 이득 불확실
551
390
 
552
391
  ---
553
392
 
554
- ## 점수 가이드라인
555
-
556
- **리렌더링 최적화 (30점):**
557
- - 25-30: React.memo 적절히 사용, 불필요한 렌더 최소
558
- - 20-24: 일부 최적화, 주요 영역에 memo 누락
559
- - 15-19: 잦은 리렌더, props에 인라인 객체/함수
560
- - 10-14: 상당한 리렌더 낭비, 메모이 없음
561
- - 0-9: Critical 이슈, 렌더 루프 또는 인터랙션당 100+ 렌더
562
-
563
- **Context 최적화 (25점):**
564
- - 20-25: 관심사별 Context 분할, 안정적 참조, selector 패턴
565
- - 15-19: 단일 context지만 최적화됨 (메모이된 값)
566
- - 10-14: Context 사용하지만 최적화 안됨 (인라인 값)
567
- - 5-9: Context 과다 사용 또는 5단계 이상 props drilling
568
- - 0-4: Critical context 성능 이슈
569
-
570
- **훅 의존성 (20점):**
571
- - 16-20: 모든 deps 정확, 안정적 참조, 적절한 cleanup
572
- - 12-15: 사소한 dep 이슈, 대부분 정확
573
- - 8-11: 여러 누락된 deps 또는 ESLint disables
574
- - 4-7: 많은 오래된 클로저 또는 잘못된 deps
575
- - 0-3: 이슈를 유발하는 Critical 의존성 버그
576
-
577
- **모던 React 패턴 (15점):**
578
- - 12-15: React 18+ 기능 적절히 사용
579
- - 9-11: 대부분 모던 패턴, 일부 레거시 코드
580
- - 6-8: 모던/레거시 혼합, 일관성 없음
581
- - 3-5: 대부분 레거시 패턴, 모던 기능 누락
582
- - 0-2: 모던 패턴 없음, deprecated API 사용
583
-
584
- **번들 크기 (10점):**
585
- - 8-10: 코드 분할, tree-shaking, lazy loading
586
- - 6-7: 일부 최적화, 개선 여지 있음
587
- - 4-5: 최소 최적화, 큰 번들
588
- - 2-3: 코드 분할 없음, 전체 라이브러리 import
589
- - 0-1: Critical 번들 크기 이슈
590
-
591
- **전체 점수:**
592
- - 90-100: 우수한 성능, 베스트 프랙티스 준수
593
- - 75-89: 좋은 성능, 사소한 최적화 필요
594
- - 60-74: 허용, 주목할 만한 개선 기회
595
- - 40-59: 우려됨, 상당한 최적화 필요
596
- - 0-39: Critical 성능 이슈, 대규모 리팩토링 필요
597
-
598
- ---
599
-
600
393
  ## References
601
394
 
602
395
  - [React Official Docs](https://react.dev)
603
396
  - [React DevTools](https://react.dev/learn/react-developer-tools)
604
397
  - [useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore)
605
398
  - [React.memo](https://react.dev/reference/react/memo)
399
+ ```