@mison/ag-kit-cn 2.0.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.
Files changed (237) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
  28. package/.agent/ARCHITECTURE.md +285 -0
  29. package/.agent/agents/backend-specialist.md +268 -0
  30. package/.agent/agents/code-archaeologist.md +106 -0
  31. package/.agent/agents/database-architect.md +225 -0
  32. package/.agent/agents/debugger.md +225 -0
  33. package/.agent/agents/devops-engineer.md +242 -0
  34. package/.agent/agents/documentation-writer.md +104 -0
  35. package/.agent/agents/explorer-agent.md +73 -0
  36. package/.agent/agents/frontend-specialist.md +618 -0
  37. package/.agent/agents/game-developer.md +162 -0
  38. package/.agent/agents/mobile-developer.md +382 -0
  39. package/.agent/agents/orchestrator.md +438 -0
  40. package/.agent/agents/penetration-tester.md +188 -0
  41. package/.agent/agents/performance-optimizer.md +187 -0
  42. package/.agent/agents/product-manager.md +112 -0
  43. package/.agent/agents/product-owner.md +95 -0
  44. package/.agent/agents/project-planner.md +405 -0
  45. package/.agent/agents/qa-automation-engineer.md +103 -0
  46. package/.agent/agents/security-auditor.md +170 -0
  47. package/.agent/agents/seo-specialist.md +111 -0
  48. package/.agent/agents/test-engineer.md +158 -0
  49. package/.agent/mcp_config.json +12 -0
  50. package/.agent/rules/GEMINI.md +273 -0
  51. package/.agent/scripts/auto_preview.py +148 -0
  52. package/.agent/scripts/checklist.py +217 -0
  53. package/.agent/scripts/session_manager.py +120 -0
  54. package/.agent/scripts/verify_all.py +327 -0
  55. package/.agent/skills/api-patterns/SKILL.md +84 -0
  56. package/.agent/skills/api-patterns/api-style.md +42 -0
  57. package/.agent/skills/api-patterns/auth.md +24 -0
  58. package/.agent/skills/api-patterns/documentation.md +26 -0
  59. package/.agent/skills/api-patterns/graphql.md +41 -0
  60. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  61. package/.agent/skills/api-patterns/response.md +37 -0
  62. package/.agent/skills/api-patterns/rest.md +40 -0
  63. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  64. package/.agent/skills/api-patterns/security-testing.md +122 -0
  65. package/.agent/skills/api-patterns/trpc.md +41 -0
  66. package/.agent/skills/api-patterns/versioning.md +22 -0
  67. package/.agent/skills/app-builder/SKILL.md +75 -0
  68. package/.agent/skills/app-builder/agent-coordination.md +74 -0
  69. package/.agent/skills/app-builder/feature-building.md +53 -0
  70. package/.agent/skills/app-builder/project-detection.md +34 -0
  71. package/.agent/skills/app-builder/scaffolding.md +118 -0
  72. package/.agent/skills/app-builder/tech-stack.md +40 -0
  73. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  74. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  75. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  76. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  77. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  78. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  79. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  80. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  81. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  82. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  83. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  84. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  85. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  86. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  87. package/.agent/skills/architecture/SKILL.md +57 -0
  88. package/.agent/skills/architecture/context-discovery.md +43 -0
  89. package/.agent/skills/architecture/examples.md +94 -0
  90. package/.agent/skills/architecture/pattern-selection.md +68 -0
  91. package/.agent/skills/architecture/patterns-reference.md +50 -0
  92. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  93. package/.agent/skills/bash-linux/SKILL.md +201 -0
  94. package/.agent/skills/behavioral-modes/SKILL.md +264 -0
  95. package/.agent/skills/brainstorming/SKILL.md +164 -0
  96. package/.agent/skills/brainstorming/dynamic-questioning.md +359 -0
  97. package/.agent/skills/clean-code/SKILL.md +200 -0
  98. package/.agent/skills/code-review-checklist/SKILL.md +125 -0
  99. package/.agent/skills/database-design/SKILL.md +54 -0
  100. package/.agent/skills/database-design/database-selection.md +43 -0
  101. package/.agent/skills/database-design/indexing.md +39 -0
  102. package/.agent/skills/database-design/migrations.md +50 -0
  103. package/.agent/skills/database-design/optimization.md +36 -0
  104. package/.agent/skills/database-design/orm-selection.md +30 -0
  105. package/.agent/skills/database-design/schema-design.md +56 -0
  106. package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
  107. package/.agent/skills/deployment-procedures/SKILL.md +241 -0
  108. package/.agent/skills/doc.md +177 -0
  109. package/.agent/skills/documentation-templates/SKILL.md +194 -0
  110. package/.agent/skills/frontend-design/SKILL.md +418 -0
  111. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  112. package/.agent/skills/frontend-design/color-system.md +307 -0
  113. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  114. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  115. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  116. package/.agent/skills/frontend-design/scripts/ux_audit.py +727 -0
  117. package/.agent/skills/frontend-design/typography-system.md +345 -0
  118. package/.agent/skills/frontend-design/ux-psychology.md +1118 -0
  119. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  120. package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
  121. package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
  122. package/.agent/skills/game-development/SKILL.md +167 -0
  123. package/.agent/skills/game-development/game-art/SKILL.md +185 -0
  124. package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
  125. package/.agent/skills/game-development/game-design/SKILL.md +129 -0
  126. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
  127. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
  128. package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
  129. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
  130. package/.agent/skills/game-development/web-games/SKILL.md +150 -0
  131. package/.agent/skills/geo-fundamentals/SKILL.md +155 -0
  132. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  133. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  134. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  135. package/.agent/skills/intelligent-routing/SKILL.md +335 -0
  136. package/.agent/skills/lint-and-validate/SKILL.md +44 -0
  137. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
  138. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  139. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  140. package/.agent/skills/mobile-design/SKILL.md +394 -0
  141. package/.agent/skills/mobile-design/decision-trees.md +516 -0
  142. package/.agent/skills/mobile-design/mobile-backend.md +491 -0
  143. package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
  144. package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
  145. package/.agent/skills/mobile-design/mobile-design-thinking.md +355 -0
  146. package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
  147. package/.agent/skills/mobile-design/mobile-performance.md +767 -0
  148. package/.agent/skills/mobile-design/mobile-testing.md +356 -0
  149. package/.agent/skills/mobile-design/mobile-typography.md +432 -0
  150. package/.agent/skills/mobile-design/platform-android.md +666 -0
  151. package/.agent/skills/mobile-design/platform-ios.md +561 -0
  152. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
  153. package/.agent/skills/mobile-design/touch-psychology.md +537 -0
  154. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +311 -0
  155. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +241 -0
  156. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +489 -0
  157. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +263 -0
  158. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
  159. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +431 -0
  160. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +683 -0
  161. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +149 -0
  162. package/.agent/skills/nextjs-react-expert/SKILL.md +286 -0
  163. package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
  164. package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
  165. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
  166. package/.agent/skills/parallel-agents/SKILL.md +194 -0
  167. package/.agent/skills/performance-profiling/SKILL.md +149 -0
  168. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  169. package/.agent/skills/plan-writing/SKILL.md +152 -0
  170. package/.agent/skills/powershell-windows/SKILL.md +166 -0
  171. package/.agent/skills/python-patterns/SKILL.md +441 -0
  172. package/.agent/skills/red-team-tactics/SKILL.md +203 -0
  173. package/.agent/skills/rust-pro/SKILL.md +190 -0
  174. package/.agent/skills/seo-fundamentals/SKILL.md +135 -0
  175. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +215 -0
  176. package/.agent/skills/server-management/SKILL.md +161 -0
  177. package/.agent/skills/systematic-debugging/SKILL.md +114 -0
  178. package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
  179. package/.agent/skills/tdd-workflow/SKILL.md +149 -0
  180. package/.agent/skills/testing-patterns/SKILL.md +178 -0
  181. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
  182. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
  183. package/.agent/skills/vulnerability-scanner/checklists.md +131 -0
  184. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +459 -0
  185. package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
  186. package/.agent/skills/webapp-testing/SKILL.md +187 -0
  187. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  188. package/.agent/workflows/brainstorm.md +113 -0
  189. package/.agent/workflows/create.md +59 -0
  190. package/.agent/workflows/debug.md +103 -0
  191. package/.agent/workflows/deploy.md +176 -0
  192. package/.agent/workflows/enhance.md +63 -0
  193. package/.agent/workflows/orchestrate.md +242 -0
  194. package/.agent/workflows/plan.md +89 -0
  195. package/.agent/workflows/preview.md +80 -0
  196. package/.agent/workflows/restore-localize-compat.md +525 -0
  197. package/.agent/workflows/status.md +86 -0
  198. package/.agent/workflows/test.md +144 -0
  199. package/.agent/workflows/ui-ux-pro-max.md +295 -0
  200. package/AGENT_FLOW.md +609 -0
  201. package/CHANGELOG.md +68 -0
  202. package/LICENSE +21 -0
  203. package/README.md +260 -0
  204. package/bin/adapters/base.js +63 -0
  205. package/bin/adapters/codex.js +391 -0
  206. package/bin/adapters/gemini.js +137 -0
  207. package/bin/ag-kit.js +1336 -0
  208. package/bin/core/builder.js +80 -0
  209. package/bin/core/generator.js +59 -0
  210. package/bin/core/resource-loader.js +64 -0
  211. package/bin/core/transformer.js +208 -0
  212. package/bin/interactive.js +65 -0
  213. package/bin/utils/atomic-writer.js +97 -0
  214. package/bin/utils/git-helper.js +68 -0
  215. package/bin/utils/managed-block.js +65 -0
  216. package/bin/utils/manifest.js +241 -0
  217. package/bin/utils.js +82 -0
  218. package/docs/codex-rules-template.md +36 -0
  219. package/docs/mapping-spec.md +68 -0
  220. package/docs/multi-target-adapter.md +80 -0
  221. package/docs/official/README.md +53 -0
  222. package/docs/official/antigravity/agent-modes-settings.md +64 -0
  223. package/docs/official/antigravity/rules-workflows.md +96 -0
  224. package/docs/official/antigravity/skills.md +147 -0
  225. package/docs/official/codex/agents-md.md +119 -0
  226. package/docs/official/codex/config-advanced.md +358 -0
  227. package/docs/official/codex/config-basic.md +141 -0
  228. package/docs/official/codex/config-reference.md +223 -0
  229. package/docs/official/codex/config-sample.md +216 -0
  230. package/docs/official/codex/mcp.md +107 -0
  231. package/docs/official/codex/rules.md +79 -0
  232. package/docs/official/codex/skills.md +114 -0
  233. package/docs/official/sources-index.md +32 -0
  234. package/docs/operations.md +145 -0
  235. package/docs/terminology-style-guide.md +69 -0
  236. package/package.json +51 -0
  237. package/scripts/postinstall-check.js +112 -0
@@ -0,0 +1,489 @@
1
+ # 3. 服务端性能 (Server-Side Performance)
2
+
3
+ > **影响:** 高 (HIGH)
4
+ > **重点:** 通过优化服务端渲染与数据获取,消除服务端瀑布流并降低响应时间。
5
+
6
+ ---
7
+
8
+ ## 概览
9
+
10
+ 本节包含 **7 条规则**,聚焦服务端性能。
11
+
12
+ ---
13
+
14
+ ## 规则 3.1:像 API 路由一样认证 Server Actions
15
+
16
+ **影响:** 严重 (CRITICAL)
17
+ **标签:** server, server-actions, authentication, security, authorization
18
+
19
+ ## 像 API 路由一样认证 Server Actions
20
+
21
+ **影响:严重 (防止未授权访问服务端变更操作)**
22
+
23
+ Server Actions(带有 `"use server"` 的函数)和 API 路由一样,都是对外公开端点。必须在每个 Server Action **内部**做认证与鉴权。不要只依赖中间件、布局守卫或页面级检查,因为 Server Actions 可以被直接调用。
24
+
25
+ Next.js 文档明确指出:“要将 Server Actions 按公开 API 端点同等安全级别对待,并验证用户是否有权限执行该变更。”
26
+
27
+ **错误示例(未做认证检查):**
28
+
29
+ ```typescript
30
+ 'use server'
31
+
32
+ export async function deleteUser(userId: string) {
33
+ // Anyone can call this! No auth check
34
+ await db.user.delete({ where: { id: userId } })
35
+ return { success: true }
36
+ }
37
+ ```
38
+
39
+ **正确示例(在 Action 内部做认证):**
40
+
41
+ ```typescript
42
+ 'use server'
43
+
44
+ import { verifySession } from '@/lib/auth'
45
+ import { unauthorized } from '@/lib/errors'
46
+
47
+ export async function deleteUser(userId: string) {
48
+ // Always check auth inside the action
49
+ const session = await verifySession()
50
+
51
+ if (!session) {
52
+ throw unauthorized('Must be logged in')
53
+ }
54
+
55
+ // Check authorization too
56
+ if (session.user.role !== 'admin' && session.user.id !== userId) {
57
+ throw unauthorized('Cannot delete other users')
58
+ }
59
+
60
+ await db.user.delete({ where: { id: userId } })
61
+ return { success: true }
62
+ }
63
+ ```
64
+
65
+ **结合输入校验:**
66
+
67
+ ```typescript
68
+ 'use server'
69
+
70
+ import { verifySession } from '@/lib/auth'
71
+ import { z } from 'zod'
72
+
73
+ const updateProfileSchema = z.object({
74
+ userId: z.string().uuid(),
75
+ name: z.string().min(1).max(100),
76
+ email: z.string().email()
77
+ })
78
+
79
+ export async function updateProfile(data: unknown) {
80
+ // Validate input first
81
+ const validated = updateProfileSchema.parse(data)
82
+
83
+ // Then authenticate
84
+ const session = await verifySession()
85
+ if (!session) {
86
+ throw new Error('Unauthorized')
87
+ }
88
+
89
+ // Then authorize
90
+ if (session.user.id !== validated.userId) {
91
+ throw new Error('Can only update own profile')
92
+ }
93
+
94
+ // Finally perform the mutation
95
+ await db.user.update({
96
+ where: { id: validated.userId },
97
+ data: {
98
+ name: validated.name,
99
+ email: validated.email
100
+ }
101
+ })
102
+
103
+ return { success: true }
104
+ }
105
+ ```
106
+
107
+ 参考: [https://nextjs.org/docs/app/guides/authentication](https://nextjs.org/docs/app/guides/authentication)
108
+
109
+ ---
110
+
111
+ ## 规则 3.2:避免在 RSC Props 中重复序列化
112
+
113
+ **影响:** 低 (LOW)
114
+ **标签:** server, rsc, serialization, props, client-components
115
+
116
+ ## 避免在 RSC Props 中重复序列化
117
+
118
+ **影响:低 (通过避免重复序列化来减少网络负载)**
119
+
120
+ RSC 到客户端的序列化是按对象引用去重,不是按值去重。相同引用只会序列化一次;新引用会再次序列化。像 `.toSorted()`、`.filter()`、`.map()` 这类转换应尽量放在客户端,而不是服务端。
121
+
122
+ **错误示例(数组被重复序列化):**
123
+
124
+ ```tsx
125
+ // RSC: sends 6 strings (2 arrays × 3 items)
126
+ <ClientList usernames={usernames} usernamesOrdered={usernames.toSorted()} />
127
+ ```
128
+
129
+ **正确示例(只发送 3 个字符串):**
130
+
131
+ ```tsx
132
+ // RSC: send once
133
+ <ClientList usernames={usernames} />
134
+
135
+ // Client: transform there
136
+ 'use client'
137
+ const sorted = useMemo(() => [...usernames].sort(), [usernames])
138
+ ```
139
+
140
+ **嵌套去重行为:**
141
+
142
+ 去重会递归生效,不同数据类型的收益不同:
143
+
144
+ - `string[]`、`number[]`、`boolean[]`:**高影响**,数组和其中的原始值都会完整重复
145
+ - `object[]`:**低影响**,数组结构会重复,但内部对象会按引用去重
146
+
147
+ ```tsx
148
+ // string[] - duplicates everything
149
+ usernames={['a','b']} sorted={usernames.toSorted()} // sends 4 strings
150
+
151
+ // object[] - duplicates array structure only
152
+ users={[{id:1},{id:2}]} sorted={users.toSorted()} // sends 2 arrays + 2 unique objects (not 4)
153
+ ```
154
+
155
+ **会破坏去重的操作(会创建新引用):**
156
+
157
+ - 数组:`.toSorted()`、`.filter()`、`.map()`、`.slice()`、`[...arr]`
158
+ - 对象:`{...obj}`、`Object.assign()`、`structuredClone()`、`JSON.parse(JSON.stringify())`
159
+
160
+ **更多示例:**
161
+
162
+ ```tsx
163
+ // ❌ Bad
164
+ <C users={users} active={users.filter(u => u.active)} />
165
+ <C product={product} productName={product.name} />
166
+
167
+ // ✅ Good
168
+ <C users={users} />
169
+ <C product={product} />
170
+ // Do filtering/destructuring in client
171
+ ```
172
+
173
+ **例外:** 如果转换计算成本较高,或客户端不需要原始数据,可直接传递派生数据。
174
+
175
+ ---
176
+
177
+ ## 规则 3.3:跨请求 LRU 缓存
178
+
179
+ **影响:** 高 (HIGH)
180
+ **标签:** server, cache, lru, cross-request
181
+
182
+ ## 跨请求 LRU 缓存
183
+
184
+ `React.cache()` 仅在单次请求内生效。对于跨连续请求共享的数据(例如用户先点按钮 A 再点按钮 B),应使用 LRU 缓存。
185
+
186
+ **实现:**
187
+
188
+ ```typescript
189
+ import { LRUCache } from 'lru-cache'
190
+
191
+ const cache = new LRUCache<string, any>({
192
+ max: 1000,
193
+ ttl: 5 * 60 * 1000 // 5 minutes
194
+ })
195
+
196
+ export async function getUser(id: string) {
197
+ const cached = cache.get(id)
198
+ if (cached) return cached
199
+
200
+ const user = await db.user.findUnique({ where: { id } })
201
+ cache.set(id, user)
202
+ return user
203
+ }
204
+
205
+ // Request 1: DB query, result cached
206
+ // Request 2: cache hit, no DB query
207
+ ```
208
+
209
+ 当用户在几秒内触发的连续操作会命中多个、且需要相同数据的端点时,优先使用这一模式。
210
+
211
+ **结合 Vercel 的 [Fluid Compute](https://vercel.com/docs/fluid-compute):** 多个并发请求可共享同一函数实例与缓存,LRU 缓存会更有效,不一定需要 Redis 这类外部存储。
212
+
213
+ **传统 serverless 场景:** 每次调用相互隔离,跨进程缓存通常需要 Redis。
214
+
215
+ 参考: [https://github.com/isaacs/node-lru-cache](https://github.com/isaacs/node-lru-cache)
216
+
217
+ ---
218
+
219
+ ## 规则 3.4:最小化 RSC 边界的序列化开销
220
+
221
+ **影响:** 高 (HIGH)
222
+ **标签:** server, rsc, serialization, props
223
+
224
+ ## 最小化 RSC 边界的序列化开销
225
+
226
+ React 的服务端/客户端边界会把对象属性序列化为字符串,并注入到 HTML 响应与后续 RSC 请求中。该数据会直接影响页面体积与加载时间,所以 **体积非常关键**。只传客户端真正需要的字段。
227
+
228
+ **错误示例(序列化了全部 50 个字段):**
229
+
230
+ ```tsx
231
+ async function Page() {
232
+ const user = await fetchUser() // 50 fields
233
+ return <Profile user={user} />
234
+ }
235
+
236
+ 'use client'
237
+ function Profile({ user }: { user: User }) {
238
+ return <div>{user.name}</div> // uses 1 field
239
+ }
240
+ ```
241
+
242
+ **正确示例(只序列化 1 个字段):**
243
+
244
+ ```tsx
245
+ async function Page() {
246
+ const user = await fetchUser()
247
+ return <Profile name={user.name} />
248
+ }
249
+
250
+ 'use client'
251
+ function Profile({ name }: { name: string }) {
252
+ return <div>{name}</div>
253
+ }
254
+ ```
255
+
256
+ ---
257
+
258
+ ## 规则 3.5:通过组件组合并行获取数据
259
+
260
+ **影响:** 严重 (CRITICAL)
261
+ **标签:** server, rsc, parallel-fetching, composition
262
+
263
+ ## 通过组件组合并行获取数据
264
+
265
+ React Server Components 在组件树内默认按顺序执行。通过重新组织组件结构,可以让数据获取并行进行。
266
+
267
+ **错误示例(Sidebar 需等待 Page 的 fetch 完成):**
268
+
269
+ ```tsx
270
+ export default async function Page() {
271
+ const header = await fetchHeader()
272
+ return (
273
+ <div>
274
+ <div>{header}</div>
275
+ <Sidebar />
276
+ </div>
277
+ )
278
+ }
279
+
280
+ async function Sidebar() {
281
+ const items = await fetchSidebarItems()
282
+ return <nav>{items.map(renderItem)}</nav>
283
+ }
284
+ ```
285
+
286
+ **正确示例(两个 fetch 同时执行):**
287
+
288
+ ```tsx
289
+ async function Header() {
290
+ const data = await fetchHeader()
291
+ return <div>{data}</div>
292
+ }
293
+
294
+ async function Sidebar() {
295
+ const items = await fetchSidebarItems()
296
+ return <nav>{items.map(renderItem)}</nav>
297
+ }
298
+
299
+ export default function Page() {
300
+ return (
301
+ <div>
302
+ <Header />
303
+ <Sidebar />
304
+ </div>
305
+ )
306
+ }
307
+ ```
308
+
309
+ **使用 `children` 的另一种写法:**
310
+
311
+ ```tsx
312
+ async function Header() {
313
+ const data = await fetchHeader()
314
+ return <div>{data}</div>
315
+ }
316
+
317
+ async function Sidebar() {
318
+ const items = await fetchSidebarItems()
319
+ return <nav>{items.map(renderItem)}</nav>
320
+ }
321
+
322
+ function Layout({ children }: { children: ReactNode }) {
323
+ return (
324
+ <div>
325
+ <Header />
326
+ {children}
327
+ </div>
328
+ )
329
+ }
330
+
331
+ export default function Page() {
332
+ return (
333
+ <Layout>
334
+ <Sidebar />
335
+ </Layout>
336
+ )
337
+ }
338
+ ```
339
+
340
+ ---
341
+
342
+ ## 规则 3.6:使用 React.cache() 做单请求去重
343
+
344
+ **影响:** 中 (MEDIUM)
345
+ **标签:** server, cache, react-cache, deduplication
346
+
347
+ ## 使用 React.cache() 做单请求去重
348
+
349
+ 使用 `React.cache()` 对服务端请求去重。认证检查和数据库查询通常收益最大。
350
+
351
+ **用法:**
352
+
353
+ ```typescript
354
+ import { cache } from 'react'
355
+
356
+ export const getCurrentUser = cache(async () => {
357
+ const session = await auth()
358
+ if (!session?.user?.id) return null
359
+ return await db.user.findUnique({
360
+ where: { id: session.user.id }
361
+ })
362
+ })
363
+ ```
364
+
365
+ 在同一次请求内,多次调用 `getCurrentUser()` 只会执行一次查询。
366
+
367
+ **避免以内联对象作为参数:**
368
+
369
+ `React.cache()` 用浅比较(`Object.is`)判断命中。内联对象每次都会创建新引用,导致无法命中缓存。
370
+
371
+ **错误示例(始终缓存未命中):**
372
+
373
+ ```typescript
374
+ const getUser = cache(async (params: { uid: number }) => {
375
+ return await db.user.findUnique({ where: { id: params.uid } })
376
+ })
377
+
378
+ // Each call creates new object, never hits cache
379
+ getUser({ uid: 1 })
380
+ getUser({ uid: 1 }) // Cache miss, runs query again
381
+ ```
382
+
383
+ **正确示例(缓存命中):**
384
+
385
+ ```typescript
386
+ const getUser = cache(async (uid: number) => {
387
+ return await db.user.findUnique({ where: { id: uid } })
388
+ })
389
+
390
+ // Primitive args use value equality
391
+ getUser(1)
392
+ getUser(1) // Cache hit, returns cached result
393
+ ```
394
+
395
+ 如果必须传对象,请复用同一个引用:
396
+
397
+ ```typescript
398
+ const params = { uid: 1 }
399
+ getUser(params) // Query runs
400
+ getUser(params) // Cache hit (same reference)
401
+ ```
402
+
403
+ **Next.js 特别说明:**
404
+
405
+ 在 Next.js 中,`fetch` 已扩展了请求级 memoization。同一个请求内,URL 和选项相同的 `fetch` 会自动去重,因此 `fetch` 场景通常不需要 `React.cache()`。但对于其他异步任务,`React.cache()` 仍然很关键:
406
+
407
+ - 数据库查询(Prisma、Drizzle 等)
408
+ - 重计算任务
409
+ - 认证检查
410
+ - 文件系统操作
411
+ - 非 fetch 的异步工作
412
+
413
+ 可用 `React.cache()` 在组件树中对这些操作做去重。
414
+
415
+ 参考: [React.cache 文档](https://react.dev/reference/react/cache)
416
+
417
+ ---
418
+
419
+ ## 规则 3.7:使用 `after()` 执行非阻塞操作
420
+
421
+ **影响:** 中 (MEDIUM)
422
+ **标签:** server, async, logging, analytics, side-effects
423
+
424
+ ## 使用 `after()` 执行非阻塞操作
425
+
426
+ 使用 Next.js 的 `after()` 安排“响应发送后再执行”的任务。这样日志、埋点和其他副作用就不会阻塞响应返回。
427
+
428
+ **错误示例(阻塞响应):**
429
+
430
+ ```tsx
431
+ import { logUserAction } from '@/app/utils'
432
+
433
+ export async function POST(request: Request) {
434
+ // Perform mutation
435
+ await updateDatabase(request)
436
+
437
+ // Logging blocks the response
438
+ const userAgent = request.headers.get('user-agent') || 'unknown'
439
+ await logUserAction({ userAgent })
440
+
441
+ return new Response(JSON.stringify({ status: 'success' }), {
442
+ status: 200,
443
+ headers: { 'Content-Type': 'application/json' }
444
+ })
445
+ }
446
+ ```
447
+
448
+ **正确示例(非阻塞):**
449
+
450
+ ```tsx
451
+ import { after } from 'next/server'
452
+ import { headers, cookies } from 'next/headers'
453
+ import { logUserAction } from '@/app/utils'
454
+
455
+ export async function POST(request: Request) {
456
+ // Perform mutation
457
+ await updateDatabase(request)
458
+
459
+ // Log after response is sent
460
+ after(async () => {
461
+ const userAgent = (await headers()).get('user-agent') || 'unknown'
462
+ const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
463
+
464
+ logUserAction({ sessionCookie, userAgent })
465
+ })
466
+
467
+ return new Response(JSON.stringify({ status: 'success' }), {
468
+ status: 200,
469
+ headers: { 'Content-Type': 'application/json' }
470
+ })
471
+ }
472
+ ```
473
+
474
+ 响应会先立即返回,日志在后台异步执行。
475
+
476
+ **常见场景:**
477
+
478
+ - 分析埋点
479
+ - 审计日志
480
+ - 发送通知
481
+ - 缓存失效
482
+ - 清理任务
483
+
484
+ **重要说明:**
485
+
486
+ - 即使响应失败或重定向,`after()` 也会执行
487
+ - 适用于 Server Actions、Route Handlers、Server Components
488
+
489
+ 参考: [https://nextjs.org/docs/app/api-reference/functions/after](https://nextjs.org/docs/app/api-reference/functions/after)