Home / Articles

90% of React Developers Optimize Re-Renders Incorrectly

Most React developers optimize re-renders the wrong way. Where React performance actually goes and which fixes help, plus a checklist for applying them.

Publisher: REACTAPP.TOP13 min read2912 words

This article is published in English.

Sources: 90% of React Developers Optimize Re-Renders Incorrectly — Here’s What Actually Works

The following notes reconstruct a practical path around “90% of React Developers Optimize Re-Renders Incorrectly — Here’s What Actually Works”. Emphasis stays on contracts, checks, and drop-in code placeholders rather than motivational framing. When working through the Overview stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

The Real Problem: We Don’t Understand When React Re-Renders

The The Real Problem We stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

The Day you Finally Opened React Profiler

The The Day you Finally stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

The Core Truth: Re-Renders Aren’t the Enemy — Unnecessary Ones Are

The The Core Truth Re-Renders stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs. The The Core Truth Re-Renders stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

Section 1: The Mental Model That Finally Made React Click

For the Section 1 The Mental stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Prefer structured outputs with schema validation over free-form prose when the next step is code or a tool call.

React = Function Execution Engine

For the React Function Execution Engine stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Colocate state with the component that owns the mutation. Lifting everything to a global store makes timing bugs harder to see.

Component(props) → JSX

Section 2: Why Your Components Re-Render More Than You Think

For the Section 2 Why Your stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Colocate state with the component that owns the mutation. Lifting everything to a global store makes timing bugs harder to see. For the Section 2 Why Your stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

1. Inline Objects & Functions

When working through the 1 Inline Objects Functions stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Treat effects as synchronization with the outside world, not as a substitute for derived values during render.

<MyComponent options={{ theme: "dark" }} />
{} !== {}
onClick={() => doSomething()}

2. State Lifted Too High

When working through the 2 State Lifted Too stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Treat effects as synchronization with the outside world, not as a substitute for derived values during render.

3. Derived State Stored as State

When working through the 3 Derived State Stored stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Treat effects as synchronization with the outside world, not as a substitute for derived values during render. When working through the 3 Derived State Stored stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

const [filtered, setFiltered] = useState([]);

useEffect(() => {
  setFiltered(items.filter(...));
}, [items]);

Section 3: The Rule That Changed Everything for Me

The Section 3 The Rule stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

Section 4: The 4 Levels of React Re-Render Control

The Section 4 The 4 stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

Level 1: Structural Optimization (Most Important)

The Level 1 Structural Optimization stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs. The Level 1 Structural Optimization stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

Level 2: Memoization (When Needed)

For the Level 2 Memoization When stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Colocate state with the component that owns the mutation. Lifting everything to a global store makes timing bugs harder to see.

Level 3: Referential Stability

For the Level 3 Referential Stability stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Colocate state with the component that owns the mutation. Lifting everything to a global store makes timing bugs harder to see.

const handler = () => doSomething();
const handler = useCallback(() => {
  doSomething();
}, []);
const config = useMemo(() => ({
  theme: "dark"
}), []);

Level 4: Architectural Isolation

For the Level 4 Architectural Isolation stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Colocate state with the component that owns the mutation. Lifting everything to a global store makes timing bugs harder to see. For the Level 4 Architectural Isolation stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

Section 5: React.memo — The Most Misused Optimization

When working through the Section 5 React memo stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Treat effects as synchronization with the outside world, not as a substitute for derived values during render.

When React.memo Does NOTHING

When working through the When React memo Does stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Treat effects as synchronization with the outside world, not as a substitute for derived values during render.

When React.memo Shines

When working through the When React memo Shines stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Treat effects as synchronization with the outside world, not as a substitute for derived values during render. When working through the When React memo Shines stage, write down the contract first: required inputs, success signal, and what happens on partial failure. That checklist keeps later code changes honest. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

Section 6: The useCallback Trap

The Section 6 The useCallback stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

const handleClick = useCallback(() => {
  setCount(c => c + 1);
}, []);

Section 7: The Hidden Cost of Context

The Section 7 The Hidden stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

Bad:

The Bad stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

<AuthContext.Provider value={{ user, theme }}>

Better:

The Better stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Prefer small, testable units over sprawling scripts. When a step fails, the failure should point at a single responsibility rather than a tangled pipeline. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

<UserContext />
<ThemeContext />

Section 8: Lists, Keys, and the Illusion of Stability

The Section 8 Lists Keys stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

items.map((item, i) => <Row key={i} />)
items.map(item => <Row key={item.id} />)

Section 9: the Personal Performance Checklist

The Section 9 the Personal stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Record timings and token or query cost next to functional results. Cost visibility early prevents surprise bills when the path moves from demo to shared environments. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

Section 10: The Big Mindset Shift

The Section 10 The Big stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Keep configuration outside application code. Environment files, secret stores, and feature flags belong in one place operators can audit without reading the whole graph. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs.

Final Thoughts: The Real Secret

The Final Thoughts The Real stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Document the happy path and the recovery path together. Retries, human gates, and dead-letter handling are part of the product, not later polish. Keep render work cheap and push expensive derivation behind memoization only after measuring. Premature memo can hide stale props bugs. The Final Thoughts The Real stage works best when treated as a measurable surface. Capture one golden transcript, one failure case, and the rollback note before expanding scope. Treat this stage as a contract between inputs and validated outputs. Name the artifacts, define success checks, and refuse silent partial completion.

React Performance & Optimization

For the React Performance Optimization stage, define the inputs, the owner of the step, and the exit criteria before changing code. Operators should be able to re-run the step from a known checkpoint without guessing hidden state.

React Hooks & State Management

React Patterns & Architecture

Real-World React Development

React Ecosystem & Tools

React Learning Path (Beginner → Advanced)

Security & Scaling React Apps

React Interviews & Career

Latest React Updates

One More That Might Surprise You

AI-Powered React Development

Operational checklist