@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,431 @@
1
+ # 6. 渲染性能 (Rendering Performance)
2
+
3
+ > **影响:** 中 (MEDIUM)
4
+ > **重点:** 优化渲染过程可以减少浏览器需要执行的工作量。
5
+
6
+ ---
7
+
8
+ ## 概览
9
+
10
+ 本节包含 **9 条规则**,聚焦渲染性能。
11
+
12
+ ---
13
+
14
+ ## 规则 6.1:优先动画化 SVG 外层容器,而非 SVG 元素本身
15
+
16
+ **影响:** 低 (LOW)
17
+ **标签:** rendering, svg, css, animation, performance
18
+
19
+ ## 优先动画化 SVG 外层容器,而非 SVG 元素本身
20
+
21
+ 许多浏览器对 SVG 元素上的 CSS3 动画缺少硬件加速。应将 SVG 包裹在 `<div>` 中,并对外层容器做动画。
22
+
23
+ **错误示例(直接对 SVG 动画,无硬件加速):**
24
+
25
+ ```tsx
26
+ function LoadingSpinner() {
27
+ return (
28
+ <svg
29
+ className="animate-spin"
30
+ width="24"
31
+ height="24"
32
+ viewBox="0 0 24 24"
33
+ >
34
+ <circle cx="12" cy="12" r="10" stroke="currentColor" />
35
+ </svg>
36
+ )
37
+ }
38
+ ```
39
+
40
+ **正确示例(对外层 div 动画,可硬件加速):**
41
+
42
+ ```tsx
43
+ function LoadingSpinner() {
44
+ return (
45
+ <div className="animate-spin">
46
+ <svg
47
+ width="24"
48
+ height="24"
49
+ viewBox="0 0 24 24"
50
+ >
51
+ <circle cx="12" cy="12" r="10" stroke="currentColor" />
52
+ </svg>
53
+ </div>
54
+ )
55
+ }
56
+ ```
57
+
58
+ 这适用于所有 CSS transform/transition(`transform`、`opacity`、`translate`、`scale`、`rotate`)。外层容器能让浏览器更容易走 GPU 加速路径,动画更流畅。
59
+
60
+ ---
61
+
62
+ ## 规则 6.2:长列表使用 CSS `content-visibility`
63
+
64
+ **影响:** 高 (HIGH)
65
+ **标签:** rendering, css, content-visibility, long-lists
66
+
67
+ ## 长列表使用 CSS `content-visibility`
68
+
69
+ 应用 `content-visibility: auto` 来延迟屏幕外内容的渲染。
70
+
71
+ **CSS:**
72
+
73
+ ```css
74
+ .message-item {
75
+ content-visibility: auto;
76
+ contain-intrinsic-size: 0 80px;
77
+ }
78
+ ```
79
+
80
+ **示例:**
81
+
82
+ ```tsx
83
+ function MessageList({ messages }: { messages: Message[] }) {
84
+ return (
85
+ <div className="overflow-y-auto h-screen">
86
+ {messages.map(msg => (
87
+ <div key={msg.id} className="message-item">
88
+ <Avatar user={msg.author} />
89
+ <div>{msg.content}</div>
90
+ </div>
91
+ ))}
92
+ </div>
93
+ )
94
+ }
95
+ ```
96
+
97
+ 在 1000 条消息场景中,浏览器可跳过约 990 个屏幕外项的 layout/paint,首屏渲染可提升约 10 倍。
98
+
99
+ ---
100
+
101
+ ## 规则 6.3:提升(Hoist)静态 JSX 元素
102
+
103
+ **影响:** 低 (LOW)
104
+ **标签:** rendering, jsx, static, optimization
105
+
106
+ ## 提升(Hoist)静态 JSX 元素
107
+
108
+ 把静态 JSX 抽离到组件外部,避免每次渲染都重新创建。
109
+
110
+ **错误示例(每次渲染都重建元素):**
111
+
112
+ ```tsx
113
+ function LoadingSkeleton() {
114
+ return <div className="animate-pulse h-20 bg-gray-200" />
115
+ }
116
+
117
+ function Container() {
118
+ return (
119
+ <div>
120
+ {loading && <LoadingSkeleton />}
121
+ </div>
122
+ )
123
+ }
124
+ ```
125
+
126
+ **正确示例(复用同一个元素):**
127
+
128
+ ```tsx
129
+ const loadingSkeleton = (
130
+ <div className="animate-pulse h-20 bg-gray-200" />
131
+ )
132
+
133
+ function Container() {
134
+ return (
135
+ <div>
136
+ {loading && loadingSkeleton}
137
+ </div>
138
+ )
139
+ }
140
+ ```
141
+
142
+ 这对大型静态 SVG 节点尤其有价值,因为它们在每次渲染中重建成本较高。
143
+
144
+ **说明:** 若项目启用 [React Compiler](https://react.dev/learn/react-compiler),编译器会自动提升静态 JSX 并优化重渲染,通常无需手动 hoist。
145
+
146
+ ---
147
+
148
+ ## 规则 6.4:优化 SVG 精度
149
+
150
+ **影响:** 低 (LOW)
151
+ **标签:** rendering, svg, optimization, svgo
152
+
153
+ ## 优化 SVG 精度
154
+
155
+ 降低 SVG 坐标精度可减小文件体积。最佳精度与 viewBox 大小相关,但通常都应评估是否可降精度。
156
+
157
+ **错误示例(精度过高):**
158
+
159
+ ```svg
160
+ <path d="M 10.293847 20.847362 L 30.938472 40.192837" />
161
+ ```
162
+
163
+ **正确示例(保留 1 位小数):**
164
+
165
+ ```svg
166
+ <path d="M 10.3 20.8 L 30.9 40.2" />
167
+ ```
168
+
169
+ **使用 SVGO 自动化:**
170
+
171
+ ```bash
172
+ npx svgo --precision=1 --multipass icon.svg
173
+ ```
174
+
175
+ ---
176
+
177
+ ## 规则 6.5:无闪烁地避免 Hydration 不匹配
178
+
179
+ **影响:** 中 (MEDIUM)
180
+ **标签:** rendering, ssr, hydration, localStorage, flicker
181
+
182
+ ## 无闪烁地避免 Hydration 不匹配
183
+
184
+ 当渲染依赖客户端存储(localStorage、cookies)时,可注入同步脚本,在 React hydration 前更新 DOM,以同时避免 SSR 崩溃和 hydration 后闪烁。
185
+
186
+ **错误示例(会破坏 SSR):**
187
+
188
+ ```tsx
189
+ function ThemeWrapper({ children }: { children: ReactNode }) {
190
+ // localStorage 在服务端不可用,会抛错
191
+ const theme = localStorage.getItem('theme') || 'light'
192
+
193
+ return (
194
+ <div className={theme}>
195
+ {children}
196
+ </div>
197
+ )
198
+ }
199
+ ```
200
+
201
+ 由于 `localStorage` 在服务端为 undefined,服务端渲染会失败。
202
+
203
+ **错误示例(出现视觉闪烁):**
204
+
205
+ ```tsx
206
+ function ThemeWrapper({ children }: { children: ReactNode }) {
207
+ const [theme, setTheme] = useState('light')
208
+
209
+ useEffect(() => {
210
+ // 在 hydration 后执行,会造成明显闪烁
211
+ const stored = localStorage.getItem('theme')
212
+ if (stored) {
213
+ setTheme(stored)
214
+ }
215
+ }, [])
216
+
217
+ return (
218
+ <div className={theme}>
219
+ {children}
220
+ </div>
221
+ )
222
+ }
223
+ ```
224
+
225
+ 组件先以默认值(`light`)渲染,hydration 后再更新,会出现错误内容的闪现。
226
+
227
+ **正确示例(无闪烁、无 hydration 不匹配):**
228
+
229
+ ```tsx
230
+ function ThemeWrapper({ children }: { children: ReactNode }) {
231
+ return (
232
+ <>
233
+ <div id="theme-wrapper">
234
+ {children}
235
+ </div>
236
+ <script
237
+ dangerouslySetInnerHTML={{
238
+ __html: `
239
+ (function() {
240
+ try {
241
+ var theme = localStorage.getItem('theme') || 'light';
242
+ var el = document.getElementById('theme-wrapper');
243
+ if (el) el.className = theme;
244
+ } catch (e) {}
245
+ })();
246
+ `,
247
+ }}
248
+ />
249
+ </>
250
+ )
251
+ }
252
+ ```
253
+
254
+ 内联脚本会在元素展示前同步执行,确保 DOM 已经具备正确值,因此不会闪烁,也不会出现 hydration 不匹配。
255
+
256
+ 这种模式特别适合主题切换、用户偏好、认证状态,以及其他需要“立即正确渲染”的纯客户端数据。
257
+
258
+ ---
259
+
260
+ ## 规则 6.6:抑制可预期的 Hydration 不匹配
261
+
262
+ **影响:** 低到中 (LOW-MEDIUM)
263
+ **标签:** rendering, hydration, ssr, nextjs
264
+
265
+ ## 抑制可预期的 Hydration 不匹配
266
+
267
+ 在 SSR 框架(如 Next.js)中,某些值本就会在服务端与客户端不同(随机 ID、日期、本地化/时区格式等)。对于这类“可预期”不匹配,可用 `suppressHydrationWarning` 包裹动态文本以避免噪声告警。不要用它掩盖真实 Bug,也不要滥用。
268
+
269
+ **错误示例(会产生已知不匹配告警):**
270
+
271
+ ```tsx
272
+ function Timestamp() {
273
+ return <span>{new Date().toLocaleString()}</span>
274
+ }
275
+ ```
276
+
277
+ **正确示例(仅抑制可预期不匹配):**
278
+
279
+ ```tsx
280
+ function Timestamp() {
281
+ return (
282
+ <span suppressHydrationWarning>
283
+ {new Date().toLocaleString()}
284
+ </span>
285
+ )
286
+ }
287
+ ```
288
+
289
+ ---
290
+
291
+ ## 规则 6.7:显示/隐藏场景使用 Activity 组件
292
+
293
+ **影响:** 中 (MEDIUM)
294
+ **标签:** rendering, activity, visibility, state-preservation
295
+
296
+ ## 显示/隐藏场景使用 Activity 组件
297
+
298
+ 对于频繁切换可见性且渲染代价高的组件,使用 React 的 `<Activity>` 保留其 state/DOM。
299
+
300
+ **用法:**
301
+
302
+ ```tsx
303
+ import { Activity } from 'react'
304
+
305
+ function Dropdown({ isOpen }: Props) {
306
+ return (
307
+ <Activity mode={isOpen ? 'visible' : 'hidden'}>
308
+ <ExpensiveMenu />
309
+ </Activity>
310
+ )
311
+ }
312
+ ```
313
+
314
+ 可避免高成本重渲染和状态丢失。
315
+
316
+ ---
317
+
318
+ ## 规则 6.8:使用显式条件渲染
319
+
320
+ **影响:** 低 (LOW)
321
+ **标签:** rendering, conditional, jsx, falsy-values
322
+
323
+ ## 使用显式条件渲染
324
+
325
+ 当条件值可能为 `0`、`NaN` 或其他可被渲染的 falsy 值时,应使用三元表达式(`? :`)而非 `&&`。
326
+
327
+ **错误示例(count 为 0 时会渲染出 "0"):**
328
+
329
+ ```tsx
330
+ function Badge({ count }: { count: number }) {
331
+ return (
332
+ <div>
333
+ {count && <span className="badge">{count}</span>}
334
+ </div>
335
+ )
336
+ }
337
+
338
+ // count = 0 时渲染:<div>0</div>
339
+ // count = 5 时渲染:<div><span class="badge">5</span></div>
340
+ ```
341
+
342
+ **正确示例(count 为 0 时不渲染内容):**
343
+
344
+ ```tsx
345
+ function Badge({ count }: { count: number }) {
346
+ return (
347
+ <div>
348
+ {count > 0 ? <span className="badge">{count}</span> : null}
349
+ </div>
350
+ )
351
+ }
352
+
353
+ // count = 0 时渲染:<div></div>
354
+ // count = 5 时渲染:<div><span class="badge">5</span></div>
355
+ ```
356
+
357
+ ---
358
+
359
+ ## 规则 6.9:优先使用 useTransition,而不是手动 Loading State
360
+
361
+ **影响:** 低 (LOW)
362
+ **标签:** rendering, transitions, useTransition, loading, state
363
+
364
+ ## 优先使用 useTransition,而不是手动 Loading State
365
+
366
+ 用 `useTransition` 替代手写 `useState` 的 loading 管理。它提供内建 `isPending`,并自动处理 transition 生命周期。
367
+
368
+ **错误示例(手动维护 loading 状态):**
369
+
370
+ ```tsx
371
+ function SearchResults() {
372
+ const [query, setQuery] = useState('')
373
+ const [results, setResults] = useState([])
374
+ const [isLoading, setIsLoading] = useState(false)
375
+
376
+ const handleSearch = async (value: string) => {
377
+ setIsLoading(true)
378
+ setQuery(value)
379
+ const data = await fetchResults(value)
380
+ setResults(data)
381
+ setIsLoading(false)
382
+ }
383
+
384
+ return (
385
+ <>
386
+ <input onChange={(e) => handleSearch(e.target.value)} />
387
+ {isLoading && <Spinner />}
388
+ <ResultsList results={results} />
389
+ </>
390
+ )
391
+ }
392
+ ```
393
+
394
+ **正确示例(使用 useTransition 的内建 pending 状态):**
395
+
396
+ ```tsx
397
+ import { useTransition, useState } from 'react'
398
+
399
+ function SearchResults() {
400
+ const [query, setQuery] = useState('')
401
+ const [results, setResults] = useState([])
402
+ const [isPending, startTransition] = useTransition()
403
+
404
+ const handleSearch = (value: string) => {
405
+ setQuery(value) // 立即更新输入框
406
+
407
+ startTransition(async () => {
408
+ // 拉取并更新结果
409
+ const data = await fetchResults(value)
410
+ setResults(data)
411
+ })
412
+ }
413
+
414
+ return (
415
+ <>
416
+ <input onChange={(e) => handleSearch(e.target.value)} />
417
+ {isPending && <Spinner />}
418
+ <ResultsList results={results} />
419
+ </>
420
+ )
421
+ }
422
+ ```
423
+
424
+ **收益:**
425
+
426
+ - **自动 pending 状态**:无需手动 `setIsLoading(true/false)`
427
+ - **更强容错**:即使 transition 抛错,pending 状态也能正确复位
428
+ - **更好响应性**:更新过程中 UI 更流畅
429
+ - **中断处理**:新 transition 会自动中断旧的等待流程
430
+
431
+ 参考: [useTransition](https://react.dev/reference/react/useTransition)