Skip to content
cccskills
FreePublished on GitHub

optimizing-react-performance

React performance optimization. Identify unnecessary renders, apply memo/useCallback/useMemo correctly.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md3.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Profile First — Never Optimize Blindly

// 1. Enable React DevTools Profiler
// 2. Record the slow interaction
// 3. Find components with long render times

// Rule: Only optimize what the profiler shows as slow

The Three Memoization Tools

React.memo — Prevent Child Re-renders

// Without memo: re-renders whenever parent re-renders (even same props)
const ExpensiveList = React.memo(({ items, onItemClick }) => {
  return items.map(item => (
    <Item key={item.id} item={item} onClick={onItemClick} />
  ));
});

// Only re-renders when items or onItemClick reference changes

useCallback — Stable Function References

// Without useCallback: new function reference every render → breaks React.memo
const Parent = () => {
  const [count, setCount] = useState(0);

  // BAD: new reference every render
  const handleClick = (id) => console.log(id);

  // GOOD: stable reference (only changes if count changes)
  const handleClick = useCallback((id) => {
    console.log(id, count);
  }, [count]);

  return <ExpensiveList onItemClick={handleClick} />;
};

useMemo — Expensive Computations

// Only use useMemo for genuinely expensive calculations
const sortedAndFilteredItems = useMemo(() => {
  return items
    .filter(item => item.active)
    .sort((a, b) => b.priority - a.priority);
}, [items]); // only recalculate when items changes

Anti-Patterns

// Anti-pattern 1: Premature optimization
const name = useMemo(() => `${first} ${last}`, [first, last]);
// String concatenation is instant — useMemo adds overhead here

// Anti-pattern 2: Object in deps breaks memoization
const options = { limit: 10 };
const result = useMemo(() => fetchData(options), [options]);
// options is a new object every render! Memoization is pointless.

// Fix: primitives in deps
const result = useMemo(() => fetchData({ limit }), [limit]);

Virtualization for Long Lists

// Don't render 10,000 items in the DOM
import { FixedSizeList } from 'react-window';

const VirtualList = ({ items }) => (
  <FixedSizeList height={600} width="100%" itemCount={items.length} itemSize={50}>
    {({ index, style }) => (
      <div style={style}>{items[index].name}</div>
    )}
  </FixedSizeList>
);

State Colocation

// Don't put state in parent if only child needs it
// BAD: every sibling re-renders when modalOpen changes
const Parent = () => {
  const [modalOpen, setModalOpen] = useState(false);
  return (
    <>
      <HeavyComponent />  {/* re-renders on every modal toggle */}
      <Modal open={modalOpen} onClose={() => setModalOpen(false)} />
    </>
  );
};

// GOOD: colocate state
const ModalWithState = () => {
  const [open, setOpen] = useState(false);
  return <Modal open={open} onClose={() => setOpen(false)} />;
};
const Parent = () => (
  <>
    <HeavyComponent />  {/* never re-renders for modal */}
    <ModalWithState />
  </>
);

Quick Wins Checklist

  • Add keys to all lists (use stable IDs, not array index)
  • Lazy-load heavy components: const Chart = lazy(() => import('./Chart'))
  • Code-split routes (Next.js does this automatically)
  • Move static values outside component body
  • Use virtualization for lists > 100 items

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

anoa

Free

Drive a real browser from the command line — open pages, snapshot the interactive elements as refs, click and fill by ref, read text, run JS, screenshot. Use when a task needs a live browser: checking a page renders, walking a login or checkout flow, scraping something that only exists after JavaScript runs, or reproducing a UI bug.

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

Run linters/typecheckers to calculate health score.

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

Comprehensive UI/UX compliance check (A11y, performance, responsive).

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

Infrastructure-first security audit (OWASP, secrets, dependencies).

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

auth

Free

Setup authentication flow (register, login, session/JWT, middleware)

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

Deep knowledge about deploying applications to AWS (EC2, ECS, S3, CloudFront, Cloud Run).

The English summary is being prepared. Showing the original description.

porcupine-md/jonggrang16Updated Sep 15, 2026

See all skills by porcupine-md

Report a problem with this skill