Official information
Basic policy of this Skill
- UI is the computation of "state → render." Design components as units of computation.
- Rendering: SSR/CSR/SSG/Streaming is the design of "when to complete the UI." Choose based on requirements (SEO/speed/update frequency).
- Boundary: Be conscious of the boundary between "JS sent to the client" and "processing placed on the server." Optimization by not sending is powerful.
- Performance: Apply in the order that affects perceived experience (LCP/INP/CLS). Suspect JS payload, images, fonts, and 3rd party.
- Reference: React / Next.js
Philosophy (decision rules)
- A component is not a "UI part" but a "unit of UI computation." Keep responsibilities and boundaries small.
- Keep state minimal. Place state at the "smallest level above the scope that depends on it" (don't lift too much / don't scatter too much).
- Re-rendering is not bad, but avoid meaningless recomputation. Look at computation cost/DOM cost/network cost separately.
- "How far to send to the client" is design. Decide by the priority of initial display and interaction experience.
- In the context of Next.js (App Router), treat the Server/Client boundary (RSC/Client Component) as "separation of responsibilities." It is not magic but the design of constraints.
Approach (question template)
Always confirm the following before proposing:
- Is this more of a "site"? Or more of an "app"? (Are there many states/interactions?)
- What matters: initial display? Interaction experience? SEO? (Priority)
- Where does the data come from? How often is it updated? (Cacheability)
- What is the speed issue? (Which of LCP/INP/CLS/TTFB)
- Are there routing/forms/authentication? (Need for separation of responsibilities)
Output format (always in this order)
- Recommended policy (1–3 lines)
- Rationale (Web constraints / DX / maintainability / performance)
- Design proposal (component boundaries / state placement / data fetching / rendering strategy / bundle & assets / cache)
- Checklist (confirm before implementation)
- Pitfalls (to avoid)
- Next actions (order of small experiments)
Checklist (for design/implementation review)
Component boundaries
- Is the component's responsibility too large? (Are display/state/side effects/data fetching too mixed together?)
- Is prop passing too deep? (Consider Context or splitting if necessary)
- Is abstraction for reuse too early? (Is unreadability winning out?)
State and side effects
- Is state minimal? (Are you holding derived state?)
- Isn't effect becoming a "filler for synchronization"? (Suspect the data flow first)
- Are the responsibilities of asynchronous processing (loading/error/retry) separated from the UI?
Rendering / Delivery
- Can you explain the reason for choosing SSR/CSR/SSG/Streaming?
- Can you explain the amount of JS sent to the client? (Have you considered the option of "not sending"?)
- Are images/fonts/3rd party not ruining the perceived experience?
Next.js (when applicable)
- Is the Server/Client boundary appropriate? (Are you leaning too much toward Client?)
- While placing data fetching close to the UI, is secret information not leaking to the client?
- Can you articulate the caching policy (update frequency/regeneration/invalidation)?
Common pitfalls
- "Just make everything Client" bloats the amount sent and worsens initial rendering and INP
- State is lifted too much, resulting in a design where a small change re-renders everything
- Increasing derived state increases synchronization mismatches, bugs, and complexity
- Starting to patch things up with useEffect makes the causes (data flow/responsibilities) invisible
- Performance improvement becomes a "memorization ritual," and the true causes (images/3rd party/communication) are left unaddressed