一键导入
dev-react-perf
React/Next.js performance optimization. Trigger when the user wants to optimize rendering, reduce re-renders, or improve Core Web Vitals.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
React/Next.js performance optimization. Trigger when the user wants to optimize rendering, reduce re-renders, or improve Core Web Vitals.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Multi-agent team orchestration with native Agent Teams. Trigger when the user wants to launch a team of agents, coordinate parallel work with inter-agent communication, or use swarm mode.
Perform a thorough code review. Use when the user requests a review, wants to verify code quality, or before merging a PR.
Context transfer between AI sessions. Trigger when the user wants to save the context, resume a task, or hand off the work to another session.
API mock configuration for tests. Trigger when the user wants to mock APIs, use MSW, or test without a backend.
Debug and resolve problems. Use when the user has a bug, an error, an unexpected behavior, or wants to understand why something is not working.
TDD development with Red-Green-Refactor cycle. Use to implement a feature by writing tests BEFORE the code. Trigger automatically when the user asks for TDD, wants to write tests first, mentions "test first", or asks to implement, add, create, fix, correct code, a new feature, a bugfix, or a functionality.
| name | dev-react-perf |
| description | React/Next.js performance optimization. Trigger when the user wants to optimize rendering, reduce re-renders, or improve Core Web Vitals. |
| allowed-tools | ["Read","Write","Edit","Bash","Glob","Grep"] |
| context | fork |
const expensiveValue = useMemo(() => {
return computeExpensiveValue(items);
}, [items]);
const handleClick = useCallback(() => {
onSubmit(formData);
}, [formData, onSubmit]);
const UserCard = memo(({ user }: Props) => {
return <div>{user.name}</div>;
});
// Components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
<Suspense fallback={<Loading />}>
<HeavyComponent />
</Suspense>
// Routes (Next.js)
const DynamicComponent = dynamic(() => import('./Component'), {
loading: () => <Skeleton />,
ssr: false,
});
import { FixedSizeList } from 'react-window';
<FixedSizeList
height={400}
itemCount={items.length}
itemSize={50}
>
{({ index, style }) => (
<div style={style}>{items[index].name}</div>
)}
</FixedSizeList>
import Image from 'next/image';
<Image
src="/photo.jpg"
alt="Description"
width={800}
height={600}
priority={isAboveFold}
placeholder="blur"
/>
| Metric | Target | Optimization |
|---|---|---|
| LCP | < 2.5s | Preload hero image, SSR |
| FID | < 100ms | Code splitting, defer JS |
| CLS | < 0.1 | Explicit dimensions |
// BAD: boolean props explosion
<Button primary large rounded disabled loading />
// GOOD: composition with variants
<Button variant="primary" size="large" shape="rounded" state="loading" />
// BETTER: compound components
<Button.Primary size="large">
<Button.Spinner /> Loading...
</Button.Primary>
// Compound component pattern
function Tabs({ children }: { children: React.ReactNode }) {
const [active, setActive] = useState(0);
return (
<TabsContext.Provider value={{ active, setActive }}>
{children}
</TabsContext.Provider>
);
}
Tabs.List = function TabList({ children }) { /* ... */ };
Tabs.Tab = function Tab({ index, children }) { /* ... */ };
Tabs.Panel = function TabPanel({ index, children }) { /* ... */ };
// Usage
<Tabs>
<Tabs.List>
<Tabs.Tab index={0}>Tab 1</Tabs.Tab>
<Tabs.Tab index={1}>Tab 2</Tabs.Tab>
</Tabs.List>
<Tabs.Panel index={0}>Content 1</Tabs.Panel>
<Tabs.Panel index={1}>Content 2</Tabs.Panel>
</Tabs>
// BAD: state in the parent (re-renders everything)
function Page() {
const [search, setSearch] = useState('');
return (
<div>
<SearchBar value={search} onChange={setSearch} />
<ExpensiveList /> {/* Unnecessary re-render! */}
<Footer /> {/* Unnecessary re-render! */}
</div>
);
}
// GOOD: state in the component that uses it
function Page() {
return (
<div>
<SearchSection /> {/* Internal state */}
<ExpensiveList /> {/* Not affected */}
<Footer /> {/* Not affected */}
</div>
);
}
// GOOD: children do not re-render when the parent changes
function ScrollTracker({ children }: { children: React.ReactNode }) {
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handler = () => setScrollY(window.scrollY);
window.addEventListener('scroll', handler);
return () => window.removeEventListener('scroll', handler);
}, []);
return (
<div>
<ScrollIndicator position={scrollY} />
{children} {/* Does NOT re-render when scrollY changes */}
</div>
);
}
// PREFER hooks over render props
// BAD: render prop (verbose, nested)
<WindowSize render={({ width }) => (
<div>{width > 768 ? <Desktop />: <Mobile />}</div>
)} />
// GOOD: custom hook (simple, composable)
function ResponsiveLayout() {
const { width } = useWindowSize();
return width > 768 ? <Desktop />: <Mobile />;
}
# Analyze the bundle
npm run build -- --analyze
# Lighthouse
npx lighthouse https://example.com
# React DevTools Profiler
# Why did you render? (debug re-renders)
npm install @welldone-software/why-did-you-render