skills/react-rendering-optimization/SKILL.md
React rendering optimization patterns — memoization, derived state, static hoisting, conditional rendering, caching. Use when reviewing or optimizing React component render performance.
npx skillsauth add ihj04982/my-cursor-settings react-rendering-optimizationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns to reduce unnecessary computation and re-creation during React renders.
When an expression is simple and returns a primitive (boolean, number, string), useMemo overhead exceeds the expression cost.
Bad:
const isLoading = useMemo(() => {
return user.isLoading || notifications.isLoading;
}, [user.isLoading, notifications.isLoading]);
Good:
const isLoading = user.isLoading || notifications.isLoading;
Default non-primitive values in memoized components create new instances every render, breaking memo().
Bad:
const UserAvatar = memo(function UserAvatar({ onClick = () => {} }: { onClick?: () => void }) {
// ...
})
Good:
const NOOP = () => {};
const UserAvatar = memo(function UserAvatar({ onClick = NOOP }: { onClick?: () => void }) {
// ...
})
Extract static JSX outside components to avoid re-creation on every render. Especially helpful for large static SVG nodes.
Bad:
function Container() {
return <div>{loading && <div className="animate-pulse h-20 bg-gray-200" />}</div>;
}
Good:
const loadingSkeleton = <div className="animate-pulse h-20 bg-gray-200" />;
function Container() {
return <div>{loading && loadingSkeleton}</div>;
}
If React Compiler is enabled, it handles this automatically.
Don't create RegExp inside render. Hoist to module scope or memoize.
Bad:
function Highlighter({ text, query }: Props) {
const regex = new RegExp(`(${query})`, 'gi')
const parts = text.split(regex)
return <>{parts.map((part, i) => ...)}</>
}
Good:
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
function Highlighter({ text, query }: Props) {
const regex = useMemo(
() => new RegExp(`(${escapeRegex(query)})`, 'gi'),
[query]
)
const parts = text.split(regex)
return <>{parts.map((part, i) => ...)}</>
}
Warning: Global regex (
/g) has mutablelastIndexstate —regex.test('foo')returnstruethenfalsealternately.
If a value can be computed from current props/state, derive it during render instead of storing in state + syncing with useEffect.
Bad:
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
Good:
const fullName = firstName + ' ' + lastName;
Reference: You Might Not Need an Effect
Use a module-level Map to memoize pure functions called repeatedly with the same inputs.
Bad:
{projects.map(project => {
const slug = slugify(project.name) // called 100+ times for same names
return <ProjectCard key={project.id} slug={slug} />
})}
Good:
const slugifyCache = new Map<string, string>()
function cachedSlugify(text: string): string {
if (slugifyCache.has(text)) return slugifyCache.get(text)!
const result = slugify(text)
slugifyCache.set(text, result)
return result
}
Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just components.
Use explicit ternary instead of && when the condition can be 0, NaN, or other falsy values that render visibly.
Bad (renders "0" when count is 0):
<div>{count && <span className="badge">{count}</span>}</div>
Good:
<div>{count > 0 ? <span className="badge">{count}</span> : null}</div>
useMemo wrapping simple primitive expressionsdevelopment
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing accessible design patterns.
research
Generate high-entropy research (자료조사) and ideas (아이디어) using Verbalized Sampling to avoid mode collapse and maximize creativity and novelty.
development
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
documentation
Sync documentation from source-of-truth (package.json, .env.example). Generates CONTRIB.md, RUNBOOK.md. Use when updating project docs or after adding scripts/env vars.