@kood/claude-code 0.4.1 → 0.5.1
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.
- package/dist/index.js +69 -12
- package/package.json +2 -1
- package/templates/.claude/PARALLEL_AGENTS.md +737 -0
- package/templates/.claude/agents/analyst.md +416 -0
- package/templates/.claude/agents/architect.md +569 -0
- package/templates/.claude/agents/code-reviewer.md +132 -133
- package/templates/.claude/agents/dependency-manager.md +93 -94
- package/templates/.claude/agents/deployment-validator.md +64 -65
- package/templates/.claude/agents/designer.md +655 -0
- package/templates/.claude/agents/document-writer.md +500 -0
- package/templates/.claude/agents/explore.md +499 -0
- package/templates/.claude/agents/git-operator.md +74 -75
- package/templates/.claude/agents/implementation-executor.md +138 -109
- package/templates/.claude/agents/ko-to-en-translator.md +18 -22
- package/templates/.claude/agents/lint-fixer.md +250 -93
- package/templates/.claude/agents/planner.md +356 -0
- package/templates/.claude/agents/refactor-advisor.md +135 -136
- package/templates/.claude/commands/bug-fix.md +296 -207
- package/templates/.claude/commands/git-all.md +199 -46
- package/templates/.claude/commands/git-session.md +113 -57
- package/templates/.claude/commands/lint-fix.md +219 -153
- package/templates/.claude/commands/lint-init.md +113 -76
- package/templates/.claude/commands/pre-deploy.md +190 -124
- package/templates/.claude/commands/refactor.md +407 -162
- package/templates/.claude/commands/version-update.md +138 -37
- package/templates/.claude/instructions/context-engineering/ANTHROPIC_CONTEXT_ENGINEERING.md +178 -0
- package/templates/.claude/instructions/context-engineering/references/claude-4x.md +215 -0
- package/templates/.claude/instructions/context-engineering/references/core-principles.md +137 -0
- package/templates/.claude/instructions/context-engineering/references/examples.md +351 -0
- package/templates/.claude/instructions/context-engineering/references/techniques.md +162 -0
- package/templates/.claude/instructions/parallel-agent-execution.md +874 -0
- package/templates/.claude/skills/docs-creator/AGENTS.md +238 -0
- package/templates/.claude/{commands/docs-creator.md → skills/docs-creator/SKILL.md} +61 -75
- package/templates/.claude/skills/docs-refactor/AGENTS.md +270 -0
- package/templates/.claude/{commands/docs-refactor.md → skills/docs-refactor/SKILL.md} +30 -44
- package/templates/.claude/skills/execute/SKILL.md +451 -0
- package/templates/.claude/skills/figma-to-code/AGENTS.md +287 -0
- package/templates/.claude/skills/figma-to-code/SKILL.md +225 -225
- package/templates/.claude/skills/figma-to-code/references/design-tokens.md +75 -73
- package/templates/.claude/skills/figma-to-code/references/figma-mcp-tools.md +73 -73
- package/templates/.claude/skills/figma-to-code/references/layout-mapping.md +104 -104
- package/templates/.claude/skills/figma-to-code/references/responsive-design.md +99 -99
- package/templates/.claude/skills/figma-to-code/references/verification.md +91 -91
- package/templates/.claude/skills/global-uiux-design/AGENTS.md +317 -0
- package/templates/.claude/skills/global-uiux-design/SKILL.md +738 -0
- package/templates/.claude/skills/global-uiux-design/references/accessibility.md +401 -0
- package/templates/.claude/skills/global-uiux-design/references/color-system.md +275 -0
- package/templates/.claude/skills/global-uiux-design/references/design-philosophy.md +206 -0
- package/templates/.claude/skills/global-uiux-design/references/design-systems.md +446 -0
- package/templates/.claude/skills/korea-uiux-design/AGENTS.md +307 -0
- package/templates/.claude/skills/korea-uiux-design/SKILL.md +170 -0
- package/templates/.claude/skills/nextjs-react-best-practices/AGENTS.md +95 -116
- package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +134 -152
- package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-event-handler-refs.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-use-latest.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-api-routes.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-defer-await.md +22 -22
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-dependencies.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-parallel.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/async-suspense-boundaries.md +21 -21
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-barrel-imports.md +18 -18
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-conditional.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-defer-third-party.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-dynamic-imports.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/bundle-preload.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/client-event-listeners.md +9 -9
- package/templates/.claude/skills/nextjs-react-best-practices/rules/client-swr-dedup.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-batch-dom-css.md +13 -13
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-function-results.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-property-access.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-cache-storage.md +10 -10
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-combine-iterations.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-early-exit.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-hoist-regexp.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-index-maps.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-length-check-first.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-min-max-loop.md +16 -16
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-set-map-lookups.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/js-tosorted-immutable.md +17 -17
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-activity.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-animate-svg-wrapper.md +11 -11
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-conditional-render.md +8 -8
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-content-visibility.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hoist-jsx.md +6 -6
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-hydration-no-flicker.md +14 -14
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rendering-svg-precision.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-defer-reads.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-dependencies.md +7 -7
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-derived-state.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-functional-setstate.md +34 -34
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-lazy-state-init.md +15 -15
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-memo.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/rerender-transitions.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-after-nonblocking.md +24 -24
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-lru.md +10 -10
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-cache-react.md +4 -4
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-parallel-fetching.md +5 -5
- package/templates/.claude/skills/nextjs-react-best-practices/rules/server-serialization.md +6 -6
- package/templates/.claude/skills/plan/SKILL.md +594 -0
- package/templates/.claude/skills/prd/SKILL.md +496 -0
- package/templates/.claude/skills/ralph/AGENTS.md +393 -0
- package/templates/.claude/skills/ralph/SKILL.md +1035 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +100 -121
- package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +139 -157
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-defer-await.md +22 -22
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-dependencies.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-loader.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/async-parallel.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-barrel-imports.md +18 -18
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-conditional.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-lazy-routes.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-preload.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-event-listeners.md +9 -9
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-tanstack-query.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-batch-dom-css.md +13 -13
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-function-results.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-property-access.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-cache-storage.md +10 -10
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-combine-iterations.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-early-exit.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-hoist-regexp.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-index-maps.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-length-check-first.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-min-max-loop.md +16 -16
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-set-map-lookups.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/js-tosorted-immutable.md +17 -17
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-animate-svg-wrapper.md +11 -11
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-conditional-render.md +8 -8
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-content-visibility.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-hoist-jsx.md +6 -6
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rendering-svg-precision.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-defer-reads.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-dependencies.md +7 -7
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-derived-state.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-functional-setstate.md +34 -34
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-lazy-state-init.md +15 -15
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-memo.md +5 -5
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-transitions.md +4 -4
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-cache-lru.md +12 -12
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +14 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-parallel-fetching.md +9 -9
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +6 -6
- package/templates/.claude/commands/agent-creator.md +0 -370
- package/templates/.claude/commands/command-creator.md +0 -524
- package/templates/.claude/commands/execute.md +0 -469
- package/templates/.claude/commands/git.md +0 -98
- package/templates/.claude/commands/plan.md +0 -526
- package/templates/.claude/commands/prd.md +0 -629
|
@@ -1,47 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nextjs-react-best-practices
|
|
3
|
-
description: React
|
|
3
|
+
description: Vercel Engineering의 React와 Next.js 성능 최적화 가이드. React 컴포넌트, Next.js 페이지 작성/리뷰/리팩토링 시 최적 성능 패턴 보장. React 컴포넌트, Next.js 페이지, 데이터 페칭, 번들 최적화, 성능 개선 작업에 트리거.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: vercel
|
|
7
7
|
version: "1.0.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Next.js React
|
|
10
|
+
# Next.js React 베스트 프랙티스
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
<communication>
|
|
17
|
-
|
|
18
|
-
## User Communication
|
|
19
|
-
|
|
20
|
-
**IMPORTANT: Always communicate with the user in Korean (한국어), even though this document is in English.**
|
|
21
|
-
|
|
22
|
-
When:
|
|
23
|
-
- Asking questions
|
|
24
|
-
- Providing summaries
|
|
25
|
-
- Explaining decisions
|
|
26
|
-
- Reporting progress
|
|
27
|
-
|
|
28
|
-
Use Korean for all user-facing communication while applying these English guidelines internally.
|
|
29
|
-
|
|
30
|
-
</communication>
|
|
12
|
+
Vercel에서 관리하는 React와 Next.js 애플리케이션 종합 성능 최적화 가이드. 8개 카테고리, 45개 규칙 포함. 영향도별 우선순위로 자동 리팩토링과 코드 생성 가이드 제공.
|
|
31
13
|
|
|
32
14
|
---
|
|
33
15
|
|
|
34
16
|
<when_to_use>
|
|
35
17
|
|
|
36
|
-
##
|
|
18
|
+
## 사용 시점
|
|
37
19
|
|
|
38
|
-
|
|
|
39
|
-
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
20
|
+
| 상황 | 설명 |
|
|
21
|
+
|------|------|
|
|
22
|
+
| **컴포넌트 작성** | React 컴포넌트, Next.js 페이지 신규 작성 |
|
|
23
|
+
| **데이터 페칭** | 클라이언트/서버 사이드 데이터 페칭 구현 |
|
|
24
|
+
| **코드 리뷰** | 성능 이슈 검토 |
|
|
25
|
+
| **리팩토링** | 기존 React/Next.js 코드 개선 |
|
|
26
|
+
| **최적화** | 번들 크기, 로딩 시간 최적화 |
|
|
45
27
|
|
|
46
28
|
</when_to_use>
|
|
47
29
|
|
|
@@ -49,18 +31,18 @@ Use Korean for all user-facing communication while applying these English guidel
|
|
|
49
31
|
|
|
50
32
|
<categories>
|
|
51
33
|
|
|
52
|
-
##
|
|
34
|
+
## 카테고리별 우선순위
|
|
53
35
|
|
|
54
|
-
|
|
|
55
|
-
|
|
56
|
-
| 1 |
|
|
57
|
-
| 2 |
|
|
58
|
-
| 3 |
|
|
59
|
-
| 4 |
|
|
60
|
-
| 5 | Re-render
|
|
61
|
-
| 6 |
|
|
62
|
-
| 7 | JavaScript
|
|
63
|
-
| 8 |
|
|
36
|
+
| 우선순위 | 카테고리 | 영향도 | 접두사 |
|
|
37
|
+
|---------|---------|--------|--------|
|
|
38
|
+
| 1 | Waterfall 제거 | **CRITICAL** | `async-` |
|
|
39
|
+
| 2 | 번들 크기 최적화 | **CRITICAL** | `bundle-` |
|
|
40
|
+
| 3 | 서버 사이드 성능 | HIGH | `server-` |
|
|
41
|
+
| 4 | 클라이언트 데이터 페칭 | MEDIUM-HIGH | `client-` |
|
|
42
|
+
| 5 | Re-render 최적화 | MEDIUM | `rerender-` |
|
|
43
|
+
| 6 | 렌더링 성능 | MEDIUM | `rendering-` |
|
|
44
|
+
| 7 | JavaScript 성능 | LOW-MEDIUM | `js-` |
|
|
45
|
+
| 8 | 고급 패턴 | LOW | `advanced-` |
|
|
64
46
|
|
|
65
47
|
</categories>
|
|
66
48
|
|
|
@@ -68,92 +50,92 @@ Use Korean for all user-facing communication while applying these English guidel
|
|
|
68
50
|
|
|
69
51
|
<rules>
|
|
70
52
|
|
|
71
|
-
##
|
|
72
|
-
|
|
73
|
-
### 1.
|
|
74
|
-
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
| `async-defer-await` |
|
|
78
|
-
| `async-parallel` |
|
|
79
|
-
| `async-dependencies` |
|
|
80
|
-
| `async-api-routes` |
|
|
81
|
-
| `async-suspense-boundaries` |
|
|
82
|
-
|
|
83
|
-
### 2.
|
|
84
|
-
|
|
85
|
-
|
|
|
86
|
-
|
|
87
|
-
| `bundle-barrel-imports` |
|
|
88
|
-
| `bundle-dynamic-imports` |
|
|
89
|
-
| `bundle-defer-third-party` |
|
|
90
|
-
| `bundle-conditional` |
|
|
91
|
-
| `bundle-preload` |
|
|
92
|
-
|
|
93
|
-
### 3.
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
| `server-cache-react` |
|
|
98
|
-
| `server-cache-lru` |
|
|
99
|
-
| `server-serialization` |
|
|
100
|
-
| `server-parallel-fetching` |
|
|
101
|
-
| `server-after-nonblocking` |
|
|
102
|
-
|
|
103
|
-
### 4.
|
|
104
|
-
|
|
105
|
-
|
|
|
106
|
-
|
|
107
|
-
| `client-swr-dedup` |
|
|
108
|
-
| `client-event-listeners` |
|
|
109
|
-
|
|
110
|
-
### 5. Re-render
|
|
111
|
-
|
|
112
|
-
|
|
|
113
|
-
|
|
114
|
-
| `rerender-defer-reads` |
|
|
115
|
-
| `rerender-memo` |
|
|
116
|
-
| `rerender-dependencies` |
|
|
117
|
-
| `rerender-derived-state` |
|
|
118
|
-
| `rerender-functional-setstate` |
|
|
119
|
-
| `rerender-lazy-state-init` |
|
|
120
|
-
| `rerender-transitions` |
|
|
121
|
-
|
|
122
|
-
### 6.
|
|
123
|
-
|
|
124
|
-
|
|
|
125
|
-
|
|
126
|
-
| `rendering-animate-svg-wrapper` |
|
|
127
|
-
| `rendering-content-visibility` |
|
|
128
|
-
| `rendering-hoist-jsx` |
|
|
129
|
-
| `rendering-svg-precision` |
|
|
130
|
-
| `rendering-hydration-no-flicker` |
|
|
131
|
-
| `rendering-activity` |
|
|
132
|
-
| `rendering-conditional-render` |
|
|
133
|
-
|
|
134
|
-
### 7. JavaScript
|
|
135
|
-
|
|
136
|
-
|
|
|
137
|
-
|
|
138
|
-
| `js-batch-dom-css` |
|
|
139
|
-
| `js-index-maps` |
|
|
140
|
-
| `js-cache-property-access` |
|
|
141
|
-
| `js-cache-function-results` |
|
|
142
|
-
| `js-cache-storage` |
|
|
143
|
-
| `js-combine-iterations` |
|
|
144
|
-
| `js-length-check-first` |
|
|
145
|
-
| `js-early-exit` |
|
|
146
|
-
| `js-hoist-regexp` |
|
|
147
|
-
| `js-min-max-loop` |
|
|
148
|
-
| `js-set-map-lookups` |
|
|
149
|
-
| `js-tosorted-immutable` |
|
|
150
|
-
|
|
151
|
-
### 8.
|
|
152
|
-
|
|
153
|
-
|
|
|
154
|
-
|
|
155
|
-
| `advanced-event-handler-refs` |
|
|
156
|
-
| `advanced-use-latest` |
|
|
53
|
+
## 빠른 참조
|
|
54
|
+
|
|
55
|
+
### 1. Waterfall 제거 (CRITICAL)
|
|
56
|
+
|
|
57
|
+
| 규칙 | 설명 |
|
|
58
|
+
|------|------|
|
|
59
|
+
| `async-defer-await` | await를 실제 사용 지점으로 이동 |
|
|
60
|
+
| `async-parallel` | 독립 작업은 Promise.all() 사용 |
|
|
61
|
+
| `async-dependencies` | 부분 의존성은 better-all 사용 |
|
|
62
|
+
| `async-api-routes` | Promise 일찍 시작, 늦게 await |
|
|
63
|
+
| `async-suspense-boundaries` | Suspense로 콘텐츠 스트리밍 |
|
|
64
|
+
|
|
65
|
+
### 2. 번들 크기 최적화 (CRITICAL)
|
|
66
|
+
|
|
67
|
+
| 규칙 | 설명 |
|
|
68
|
+
|------|------|
|
|
69
|
+
| `bundle-barrel-imports` | 직접 import, barrel 파일 회피 |
|
|
70
|
+
| `bundle-dynamic-imports` | 무거운 컴포넌트는 next/dynamic 사용 |
|
|
71
|
+
| `bundle-defer-third-party` | 분석/로깅은 hydration 후 로드 |
|
|
72
|
+
| `bundle-conditional` | 기능 활성화 시에만 모듈 로드 |
|
|
73
|
+
| `bundle-preload` | hover/focus 시 preload로 체감 속도 향상 |
|
|
74
|
+
|
|
75
|
+
### 3. 서버 사이드 성능 (HIGH)
|
|
76
|
+
|
|
77
|
+
| 규칙 | 설명 |
|
|
78
|
+
|------|------|
|
|
79
|
+
| `server-cache-react` | React.cache()로 요청별 중복 제거 |
|
|
80
|
+
| `server-cache-lru` | LRU 캐시로 요청 간 캐싱 |
|
|
81
|
+
| `server-serialization` | 클라이언트로 전달 데이터 최소화 |
|
|
82
|
+
| `server-parallel-fetching` | 컴포넌트 재구성으로 병렬 페칭 |
|
|
83
|
+
| `server-after-nonblocking` | after()로 비차단 작업 실행 |
|
|
84
|
+
|
|
85
|
+
### 4. 클라이언트 데이터 페칭 (MEDIUM-HIGH)
|
|
86
|
+
|
|
87
|
+
| 규칙 | 설명 |
|
|
88
|
+
|------|------|
|
|
89
|
+
| `client-swr-dedup` | SWR로 자동 요청 중복 제거 |
|
|
90
|
+
| `client-event-listeners` | 전역 이벤트 리스너 중복 제거 |
|
|
91
|
+
|
|
92
|
+
### 5. Re-render 최적화 (MEDIUM)
|
|
93
|
+
|
|
94
|
+
| 규칙 | 설명 |
|
|
95
|
+
|------|------|
|
|
96
|
+
| `rerender-defer-reads` | 콜백 전용 상태는 구독 안 함 |
|
|
97
|
+
| `rerender-memo` | 비싼 작업은 memoized 컴포넌트로 추출 |
|
|
98
|
+
| `rerender-dependencies` | effect에 원시값 의존성 사용 |
|
|
99
|
+
| `rerender-derived-state` | 파생 boolean 구독, raw 값 구독 회피 |
|
|
100
|
+
| `rerender-functional-setstate` | 안정적 콜백용 함수형 setState |
|
|
101
|
+
| `rerender-lazy-state-init` | 비싼 초기값은 함수로 useState에 전달 |
|
|
102
|
+
| `rerender-transitions` | 비긴급 업데이트는 startTransition |
|
|
103
|
+
|
|
104
|
+
### 6. 렌더링 성능 (MEDIUM)
|
|
105
|
+
|
|
106
|
+
| 규칙 | 설명 |
|
|
107
|
+
|------|------|
|
|
108
|
+
| `rendering-animate-svg-wrapper` | SVG 대신 wrapper div 애니메이션 |
|
|
109
|
+
| `rendering-content-visibility` | 긴 리스트는 content-visibility 사용 |
|
|
110
|
+
| `rendering-hoist-jsx` | 정적 JSX 컴포넌트 외부로 추출 |
|
|
111
|
+
| `rendering-svg-precision` | SVG 좌표 정밀도 감소 |
|
|
112
|
+
| `rendering-hydration-no-flicker` | 인라인 스크립트로 클라이언트 전용 데이터 처리 |
|
|
113
|
+
| `rendering-activity` | show/hide는 Activity 컴포넌트 사용 |
|
|
114
|
+
| `rendering-conditional-render` | 조건부 렌더링은 &&가 아닌 삼항 연산자 |
|
|
115
|
+
|
|
116
|
+
### 7. JavaScript 성능 (LOW-MEDIUM)
|
|
117
|
+
|
|
118
|
+
| 규칙 | 설명 |
|
|
119
|
+
|------|------|
|
|
120
|
+
| `js-batch-dom-css` | CSS 변경은 클래스나 cssText로 그룹화 |
|
|
121
|
+
| `js-index-maps` | 반복 조회용 Map 빌드 |
|
|
122
|
+
| `js-cache-property-access` | 루프에서 객체 속성 캐싱 |
|
|
123
|
+
| `js-cache-function-results` | 함수 결과를 모듈 레벨 Map에 캐싱 |
|
|
124
|
+
| `js-cache-storage` | localStorage/sessionStorage 읽기 캐싱 |
|
|
125
|
+
| `js-combine-iterations` | 여러 filter/map을 하나의 루프로 결합 |
|
|
126
|
+
| `js-length-check-first` | 비싼 비교 전 배열 길이 먼저 체크 |
|
|
127
|
+
| `js-early-exit` | 함수에서 조기 반환 |
|
|
128
|
+
| `js-hoist-regexp` | RegExp 생성을 루프 밖으로 |
|
|
129
|
+
| `js-min-max-loop` | sort 대신 루프로 min/max |
|
|
130
|
+
| `js-set-map-lookups` | O(1) 조회용 Set/Map 사용 |
|
|
131
|
+
| `js-tosorted-immutable` | 불변성용 toSorted() 사용 |
|
|
132
|
+
|
|
133
|
+
### 8. 고급 패턴 (LOW)
|
|
134
|
+
|
|
135
|
+
| 규칙 | 설명 |
|
|
136
|
+
|------|------|
|
|
137
|
+
| `advanced-event-handler-refs` | ref에 이벤트 핸들러 저장 |
|
|
138
|
+
| `advanced-use-latest` | 안정적 콜백 ref용 useLatest |
|
|
157
139
|
|
|
158
140
|
</rules>
|
|
159
141
|
|
|
@@ -161,17 +143,17 @@ Use Korean for all user-facing communication while applying these English guidel
|
|
|
161
143
|
|
|
162
144
|
<patterns>
|
|
163
145
|
|
|
164
|
-
##
|
|
146
|
+
## 핵심 패턴
|
|
165
147
|
|
|
166
|
-
### ✅
|
|
148
|
+
### ✅ Waterfall 제거
|
|
167
149
|
|
|
168
150
|
```typescript
|
|
169
|
-
// ❌
|
|
151
|
+
// ❌ 순차 실행, 3번 왕복
|
|
170
152
|
const user = await fetchUser()
|
|
171
153
|
const posts = await fetchPosts()
|
|
172
154
|
const comments = await fetchComments()
|
|
173
155
|
|
|
174
|
-
// ✅
|
|
156
|
+
// ✅ 병렬 실행, 1번 왕복
|
|
175
157
|
const [user, posts, comments] = await Promise.all([
|
|
176
158
|
fetchUser(),
|
|
177
159
|
fetchPosts(),
|
|
@@ -179,18 +161,18 @@ const [user, posts, comments] = await Promise.all([
|
|
|
179
161
|
])
|
|
180
162
|
```
|
|
181
163
|
|
|
182
|
-
### ✅
|
|
164
|
+
### ✅ 번들 최적화
|
|
183
165
|
|
|
184
166
|
```tsx
|
|
185
|
-
// ❌
|
|
167
|
+
// ❌ 전체 라이브러리 import (1583개 모듈, ~2.8초)
|
|
186
168
|
import { Check, X, Menu } from 'lucide-react'
|
|
187
169
|
|
|
188
|
-
// ✅
|
|
170
|
+
// ✅ 직접 import (3개 모듈만)
|
|
189
171
|
import Check from 'lucide-react/dist/esm/icons/check'
|
|
190
172
|
import X from 'lucide-react/dist/esm/icons/x'
|
|
191
173
|
import Menu from 'lucide-react/dist/esm/icons/menu'
|
|
192
174
|
|
|
193
|
-
// ✅ Next.js 13.5+
|
|
175
|
+
// ✅ Next.js 13.5+ 자동 최적화
|
|
194
176
|
// next.config.js
|
|
195
177
|
module.exports = {
|
|
196
178
|
experimental: {
|
|
@@ -199,12 +181,12 @@ module.exports = {
|
|
|
199
181
|
}
|
|
200
182
|
```
|
|
201
183
|
|
|
202
|
-
### ✅
|
|
184
|
+
### ✅ 서버 캐싱
|
|
203
185
|
|
|
204
186
|
```typescript
|
|
205
187
|
import { cache } from 'react'
|
|
206
188
|
|
|
207
|
-
//
|
|
189
|
+
// 요청별 중복 제거
|
|
208
190
|
export const getCurrentUser = cache(async () => {
|
|
209
191
|
const session = await auth()
|
|
210
192
|
if (!session?.user?.id) return null
|
|
@@ -212,15 +194,15 @@ export const getCurrentUser = cache(async () => {
|
|
|
212
194
|
})
|
|
213
195
|
```
|
|
214
196
|
|
|
215
|
-
### ✅ Re-render
|
|
197
|
+
### ✅ Re-render 최적화
|
|
216
198
|
|
|
217
199
|
```tsx
|
|
218
|
-
// ❌ items
|
|
200
|
+
// ❌ items가 의존성, 매번 재생성
|
|
219
201
|
const addItems = useCallback((newItems: Item[]) => {
|
|
220
202
|
setItems([...items, ...newItems])
|
|
221
203
|
}, [items])
|
|
222
204
|
|
|
223
|
-
// ✅
|
|
205
|
+
// ✅ 안정적 콜백, 재생성 없음
|
|
224
206
|
const addItems = useCallback((newItems: Item[]) => {
|
|
225
207
|
setItems(curr => [...curr, ...newItems])
|
|
226
208
|
}, [])
|
|
@@ -232,9 +214,9 @@ const addItems = useCallback((newItems: Item[]) => {
|
|
|
232
214
|
|
|
233
215
|
<usage>
|
|
234
216
|
|
|
235
|
-
##
|
|
217
|
+
## 사용법
|
|
236
218
|
|
|
237
|
-
|
|
219
|
+
**상세 규칙 및 예시:**
|
|
238
220
|
|
|
239
221
|
```
|
|
240
222
|
rules/async-parallel.md
|
|
@@ -242,13 +224,13 @@ rules/bundle-barrel-imports.md
|
|
|
242
224
|
rules/_sections.md
|
|
243
225
|
```
|
|
244
226
|
|
|
245
|
-
|
|
246
|
-
-
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
-
|
|
227
|
+
각 규칙 파일 포함 내용:
|
|
228
|
+
- 중요한 이유 설명
|
|
229
|
+
- ❌ 잘못된 코드 예시 + 설명
|
|
230
|
+
- ✅ 올바른 코드 예시 + 설명
|
|
231
|
+
- 추가 컨텍스트 및 참조
|
|
250
232
|
|
|
251
|
-
|
|
233
|
+
**전체 컴파일 문서:** `PARALLEL_AGENTS.md`
|
|
252
234
|
|
|
253
235
|
</usage>
|
|
254
236
|
|
|
@@ -256,14 +238,14 @@ Each rule file contains:
|
|
|
256
238
|
|
|
257
239
|
<references>
|
|
258
240
|
|
|
259
|
-
##
|
|
241
|
+
## 참고 자료
|
|
260
242
|
|
|
261
|
-
1. [React](https://react.dev)
|
|
262
|
-
2. [Next.js](https://nextjs.org)
|
|
243
|
+
1. [React 공식 문서](https://react.dev)
|
|
244
|
+
2. [Next.js 공식 문서](https://nextjs.org)
|
|
263
245
|
3. [SWR](https://swr.vercel.app)
|
|
264
246
|
4. [better-all](https://github.com/shuding/better-all)
|
|
265
247
|
5. [node-lru-cache](https://github.com/isaacs/node-lru-cache)
|
|
266
|
-
6. [Next.js Package Import
|
|
267
|
-
7. [
|
|
248
|
+
6. [Next.js Package Import 최적화](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)
|
|
249
|
+
7. [Vercel Dashboard 2배 빠르게 만들기](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)
|
|
268
250
|
|
|
269
251
|
</references>
|
package/templates/.claude/skills/nextjs-react-best-practices/rules/advanced-event-handler-refs.md
CHANGED
|
@@ -5,11 +5,11 @@ impactDescription: stable subscriptions
|
|
|
5
5
|
tags: advanced, hooks, refs, event-handlers, optimization
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 이벤트 핸들러를 Ref에 저장
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
콜백 변경 시 재구독하지 않아야 하는 이펙트에서 사용되는 콜백은 ref에 저장하세요.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**❌ 잘못된 예 (매 렌더마다 재구독):**
|
|
13
13
|
|
|
14
14
|
```tsx
|
|
15
15
|
function useWindowEvent(event: string, handler: () => void) {
|
|
@@ -20,7 +20,7 @@ function useWindowEvent(event: string, handler: () => void) {
|
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**✅ 올바른 예 (안정적인 구독):**
|
|
24
24
|
|
|
25
25
|
```tsx
|
|
26
26
|
function useWindowEvent(event: string, handler: () => void) {
|
|
@@ -37,7 +37,7 @@ function useWindowEvent(event: string, handler: () => void) {
|
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
**대안: 최신 React를 사용하는 경우 `useEffectEvent` 사용:**
|
|
41
41
|
|
|
42
42
|
```tsx
|
|
43
43
|
import { useEffectEvent } from 'react'
|
|
@@ -52,4 +52,4 @@ function useWindowEvent(event: string, handler: () => void) {
|
|
|
52
52
|
}
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
`useEffectEvent
|
|
55
|
+
`useEffectEvent`는 동일한 패턴에 대해 더 깨끗한 API를 제공합니다: 항상 최신 버전의 핸들러를 호출하는 안정적인 함수 참조를 생성합니다.
|
|
@@ -5,11 +5,11 @@ impactDescription: prevents effect re-runs
|
|
|
5
5
|
tags: advanced, hooks, useLatest, refs, optimization
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 안정적인 콜백 Ref를 위한 useLatest
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
의존성 배열에 추가하지 않고 콜백에서 최신 값에 접근하세요. 오래된 클로저를 피하면서 이펙트 재실행을 방지합니다.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**구현:**
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
function useLatest<T>(value: T) {
|
|
@@ -21,7 +21,7 @@ function useLatest<T>(value: T) {
|
|
|
21
21
|
}
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
**❌ 잘못된 예 (매 콜백 변경마다 이펙트 재실행):**
|
|
25
25
|
|
|
26
26
|
```tsx
|
|
27
27
|
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
|
|
@@ -34,7 +34,7 @@ function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
|
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
**✅ 올바른 예 (안정적인 이펙트, 신선한 콜백):**
|
|
38
38
|
|
|
39
39
|
```tsx
|
|
40
40
|
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
|
|
@@ -5,11 +5,11 @@ impactDescription: 2-10× improvement
|
|
|
5
5
|
tags: api-routes, server-actions, waterfalls, parallelization
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## API 라우트에서 워터폴 체인 방지
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
API 라우트와 Server Actions에서는 아직 await하지 않더라도 독립적인 작업을 즉시 시작합니다.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**잘못된 예 (config가 auth를 기다리고, data가 둘 다 기다림):**
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
export async function GET(request: Request) {
|
|
@@ -20,7 +20,7 @@ export async function GET(request: Request) {
|
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**올바른 예 (auth와 config가 즉시 시작됨):**
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
export async function GET(request: Request) {
|
|
@@ -35,4 +35,4 @@ export async function GET(request: Request) {
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
더 복잡한 의존성 체인을 가진 작업의 경우, `better-all`을 사용하여 자동으로 병렬성을 최대화할 수 있습니다 (의존성 기반 병렬화 참조).
|
|
@@ -5,76 +5,76 @@ impactDescription: avoids blocking unused code paths
|
|
|
5
5
|
tags: async, await, conditional, optimization
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 필요할 때까지 Await 지연하기
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
`await` 연산을 실제로 사용하는 분기로 이동하여 불필요한 코드 경로가 차단되는 것을 방지합니다.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**잘못된 예 (두 분기 모두 차단):**
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
async function handleRequest(userId: string, skipProcessing: boolean) {
|
|
16
16
|
const userData = await fetchUserData(userId)
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
if (skipProcessing) {
|
|
19
|
-
//
|
|
19
|
+
// 즉시 반환하지만 여전히 userData를 기다림
|
|
20
20
|
return { skipped: true }
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
//
|
|
22
|
+
|
|
23
|
+
// 이 분기만 userData를 사용함
|
|
24
24
|
return processUserData(userData)
|
|
25
25
|
}
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
**올바른 예 (필요할 때만 차단):**
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
31
|
async function handleRequest(userId: string, skipProcessing: boolean) {
|
|
32
32
|
if (skipProcessing) {
|
|
33
|
-
//
|
|
33
|
+
// 대기 없이 즉시 반환
|
|
34
34
|
return { skipped: true }
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
//
|
|
36
|
+
|
|
37
|
+
// 필요할 때만 가져오기
|
|
38
38
|
const userData = await fetchUserData(userId)
|
|
39
39
|
return processUserData(userData)
|
|
40
40
|
}
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
**또 다른 예시 (조기 반환 최적화):**
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
//
|
|
46
|
+
// ❌ 잘못된 예: 항상 권한을 가져옴
|
|
47
47
|
async function updateResource(resourceId: string, userId: string) {
|
|
48
48
|
const permissions = await fetchPermissions(userId)
|
|
49
49
|
const resource = await getResource(resourceId)
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
if (!resource) {
|
|
52
52
|
return { error: 'Not found' }
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
if (!permissions.canEdit) {
|
|
56
56
|
return { error: 'Forbidden' }
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
return await updateResourceData(resource, permissions)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
//
|
|
62
|
+
// ✅ 올바른 예: 필요할 때만 가져옴
|
|
63
63
|
async function updateResource(resourceId: string, userId: string) {
|
|
64
64
|
const resource = await getResource(resourceId)
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
if (!resource) {
|
|
67
67
|
return { error: 'Not found' }
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
const permissions = await fetchPermissions(userId)
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
if (!permissions.canEdit) {
|
|
73
73
|
return { error: 'Forbidden' }
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
return await updateResourceData(resource, permissions)
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
이 최적화는 건너뛰는 분기가 자주 실행되거나 지연된 작업이 비용이 큰 경우 특히 유용합니다.
|
|
@@ -5,11 +5,11 @@ impactDescription: 2-10× improvement
|
|
|
5
5
|
tags: async, parallelization, dependencies, better-all
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 의존성 기반 병렬화
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
부분적으로 의존성이 있는 작업의 경우 `better-all`을 사용하여 병렬성을 최대화합니다. 각 작업을 가능한 빠른 시점에 자동으로 시작합니다.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**잘못된 예 (profile이 불필요하게 config를 기다림):**
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
const [user, config] = await Promise.all([
|
|
@@ -19,7 +19,7 @@ const [user, config] = await Promise.all([
|
|
|
19
19
|
const profile = await fetchProfile(user.id)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
**올바른 예 (config와 profile이 병렬로 실행됨):**
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
import { all } from 'better-all'
|
|
@@ -33,4 +33,4 @@ const { user, config, profile } = await all({
|
|
|
33
33
|
})
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
참고: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
|