React and Next.js performance optimization patterns. Use when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance. Triggers on tasks involving components, data fetching, bundle optimization, re-render reduction, or server component architecture.
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install react-performance或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install react-performance⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/react-performance/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- name: react-performance model: standard description: React and Next.js performance optimization patterns. Use when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance. Triggers on tasks involving components, data fetching, bundle optimization, re-render reduction, or server component architecture. version: "1.0" ---
Performance optimization guide for React and Next.js applications. Patterns across 7 categories, prioritized by impact. Detailed examples in references/.
| # | Category | Impact | |---|----------------------|------------| | 1 | Async / Waterfalls | CRITICAL | | 2 | Bundle Size | CRITICAL | | 3 | Server Components | HIGH | | 4 | Re-renders | MEDIUM | | 5 | Rendering | MEDIUM | | 6 | Client-Side Data | MEDIUM | | 7 | JS Performance | LOW-MEDIUM |
npx clawhub@latest install react-performance
---
Sequential awaits are the single biggest performance mistake in React apps.
// BAD — sequential, 3 round trips
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()
// GOOD — parallel, 1 round trip
const [user, posts, comments] = await Promise.all([
fetchUser(), fetchPosts(), fetchComments(),
])
Move await into branches where the value is actually used.
// BAD — blocks both branches
async function handle(userId: string, skip: boolean) {
const data = await fetchUserData(userId)
if (skip) return { skipped: true } // Still waited
return process(data)
}
// GOOD — only blocks when needed
async function handle(userId: string, skip: boolean) {
if (skip) return { skipped: true } // Returns immediately
return process(await fetchUserData(userId))
}
Show layout immediately while data-dependent sections load independently.
// BAD — entire page blocked
async function Page() {
const data = await fetchData()
return <div><Sidebar /><Header /><DataDisplay data={data} /><Footer /></div>
}
// GOOD — layout renders immediately, data streams in
function Page() {
return (
<div>
<Sidebar /><Header />
<Suspense fallback={<Skeleton />}><DataDisplay /></Suspense>
<Footer />
</div>
)
}
async function DataDisplay() {
const data = await fetchData()
return <div>{data.content}</div>
}
Share a promise across components with use() to avoid duplicate fetches.
---
Barrel files load thousands of unused modules. Direct imports save 200-800ms.
// BAD — loads 1,583 modules
import { Check, X, Menu } from 'lucide-react'
// GOOD — loads only 3 modules
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
import Menu from 'lucide-react/dist/esm/icons/menu'
Next.js 13.5+: use experimental.optimizePackageImports in config. Commonly affected: lucide-react, @mui/material, react-icons, @radix-ui, lodash, date-fns.
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
() => import('./monaco-editor').then((m) => m.MonacoEditor),
{ ssr: false }
)
Analytics, logging, error tracking — load after hydration with dynamic() and { ssr: false }.
const preload = () => { void import('./monaco-editor') }
<button onMouseEnter={preload} onFocus={preload} onClick={onClick}>Open Editor</button>
---
Only pass fields the client actually uses across the server/client boundary.
// BAD — serializes all 50 user fields
return <Profile user={user} />
// GOOD — serializes 1 field
return <Profile name={user.name} />
RSC execute sequentially within a tree. Restructure to parallelize.
// BAD — Sidebar waits for header fetch
export default async function Page() {
const header = await fetchHeader()
return <div><div>{header}</div><Sidebar /></div>
}
// GOOD — sibling async components fetch simultaneously
async function Header() { return <div>{await fetchHeader()}</div> }
async function Sidebar() { return <nav>{(await fetchSidebarItems()).map(renderItem)}</nav> }
export default function Page() { return <div><Header /><Sidebar /></div> }
import { cache } from 'react'
export const getCurrentUser = cache(async () => {
const session = await auth()
if (!session?.user?.id) return null
return await db.user.findUnique({ where: { id: session.user.id } })
})
Use primitive args (not inline objects) — React.cache() uses Object.is. Next.js auto-deduplicates fetch, but React.cache() is needed for DB queries, auth checks, and computations.
import { after } from 'next/server'
export async function POST(request: Request) {
await updateDatabase(request)
after(async () => { logUserAction({ userAgent: request.headers.get('user-agent') }) })
return Response.json({ status: 'success' })
}
---
// BAD — redundant state + effect
const [fullName, setFullName] = useState('')
useEffect(() => { setFullName(first + ' ' + last) }, [first, last])
// GOOD — derive inline
const fullName = first + ' ' + last
// BAD — recreated on every items change
const addItem = useCallback((item: Item) => {
setItems([...items, item])
}, [items])
// GOOD — stable, always latest state
const addItem = useCallback((item: Item) => {
setItems((curr) => [...curr, item])
}, [])
Don't subscribe to dynamic state if you only read it in callbacks.
// BAD — re-renders on every searchParams change
const searchParams = useSearchParams()
const handleShare = () => shareChat(chatId, { ref: searchParams.get('ref') })
// GOOD — reads on demand
const handleShare = () => {
const ref = new URLSearchParams(window.location.search).get('ref')
shareChat(chatId, { ref })
}
// BAD — JSON.parse runs every render
const [settings] = useState(JSON.parse(localStorage.getItem('s') || '{}'))
// GOOD — runs only once
const [settings] = useState(() => JSON.parse(localStorage.getItem('s') || '{}'))
// BAD — re-renders on every pixel
const width = useWindowWidth(); const isMobile = width < 768
// GOOD — re-renders only when boolean flips
const isMobile = useMediaQuery('(max-width: 767px)')
// BAD — blocks UI on scroll
const handler = () => setScrollY(window.scrollY)
// GOOD — non-blocking
const handler = () => startTransition(() => setScrollY(window.scrollY))
const UserAvatar = memo(function UserAvatar({ user }: { user: User }) {
const id = useMemo(() => computeAvatarId(user), [user])
return <Avatar id={id} />
})
function Profile({ user, loading }: Props) {
if (loading) return <Skeleton />
return <div><UserAvatar user={user} /></div>
}
Note: React Compiler makes manual memo()/useMemo() unnecessary.
---
...
安装 React Performance 后,可以对 AI 说这些话来触发它
Help me get started with React Performance
Explains what React Performance does, walks through the setup, and runs a quick demo based on your current project
Use React Performance to react and Next
Invokes React Performance with the right parameters and returns the result directly in the conversation
What can I do with React Performance in my developer & devops workflow?
Lists the top use cases for React Performance, with example commands for each scenario
将技能文件夹放到 ~/.claude/skills/react-performance/ 目录(个人级,所有项目可用),或 .claude/skills/react-performance/(项目级)。重启 AI 客户端后,用 /react-performance 主动调用,或让 AI 根据上下文自动发现并使用。
React Performance 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
React Performance 可免费安装使用。请查阅仓库了解许可证信息。
React and Next.js performance optimization patterns. Use when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance. Triggers on tasks involving components, data fetching, bundle optimization, re-render reduction, or server component architecture.
React Performance 属于「Developer & DevOps」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。
Automate my developer & devops tasks using React Performance
Identifies repetitive steps in your workflow and sets up React Performance to handle them automatically