Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A React component running again is not automatically a performance problem. To find out why your React app feels slow, profile the interaction that lags, identify which component is doing costly work and what triggered it, then fix the update pattern before adding memoization.

What a React re-render actually means

A component can render because its parent rendered, its own state changed, or a context it consumes changed. Rendering means React calls component code to calculate what the UI should look like; committing is the separate step where React applies necessary changes to the DOM. A render does not necessarily mean the browser visibly changed anything. See React’s explanation of render and commit.

So “too many renders” is best treated as a symptom to investigate, not a diagnosis. Focus on whether a specific interaction spends meaningful time doing avoidable work. If the render work is cheap and the interaction is responsive, reducing the render count may not improve anything users can notice.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to find the work that matters

Profile one slow interaction

Reproduce a single interaction that feels slow—such as typing into a search field or opening a panel—and record it with the React Developer Tools Profiler. Alternatively, wrap the subtree you want to measure in React’s <Profiler> API. The Profiler reports actualDuration, the time spent rendering the subtree for that update, and baseDuration, an estimate of the subtree’s render cost without optimizations. Compare those values for the same interaction before and after a change; they help assess React render work, not every source of delay in the browser. Profiling adds overhead and is disabled in production by default; production profiling requires a special profiling build. Details: React’s Profiler reference.

Trace the update trigger

Starting with the component doing the expensive work, ask what caused it to render:

  • Did its own state change?
  • Did its parent render?
  • Did a context value it consumes change?
  • Did an Effect schedule another update?

These causes call for different fixes. In particular, a memoized component can still render when its own state or consumed context changes; memoization does not block every update.

Fix update structure before adding memoization

Keep transient state close to where it is used

Interaction state that only matters to one part of the interface usually does not need to live high in the tree. Keeping it near the components that use it can reduce how much of the tree responds when that state changes. Choose the state owner based on which components actually need the value, rather than lifting every piece of state to a common ancestor by default.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not mirror values you can derive

A common source of avoidable update chains is an Effect that copies or calculates a value already available from props or existing state. Derive that value during render instead of storing a duplicate and setting it in an Effect. React’s guide, You Might Not Need an Effect, explains when calculations belong in rendering rather than an Effect.

Effects are appropriate for synchronizing with external systems, but using one simply to keep redundant state in sync can cause an extra update. Simplifying the data flow is often clearer than trying to optimize the resulting renders afterward.

Consider passing JSX through wrapper components

If a wrapper’s own state changes but its content does not depend on that state, passing the content as JSX children can help keep the content from being needlessly recalculated by the wrapper’s parent-driven render. This is a structural option, not a guarantee that every child will avoid rendering; check the actual update path and profile the result.

When memoization helps—and when it does not

memo: skip some parent-driven renders

memo lets React skip rendering a component when it renders because its parent updated and its props compare equal. By default, React compares each prop with Object.is (a shallow, per-prop identity/value comparison). A newly created object, array, or function is a different reference, even if its contents or behavior look equivalent, and can therefore defeat the comparison. A memoized component still renders when its own state or consumed context changes, and memo is an optimization rather than a guarantee. Read React’s memo reference.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use it when profiling shows an expensive child repeatedly rendering from a parent update despite unchanged semantic inputs. Prefer passing simpler props when that makes the inputs naturally stable; do not add a memo boundary merely to make render counts look smaller.

useMemo and useCallback: stabilize specific values

useMemo caches a calculation result, while useCallback caches a function identity. Their caches are reused while dependencies remain equal under Object.is. They can help when a measured expensive calculation should not repeat or when a memoized child needs a stable object or callback prop. They do not fix an incorrect state model or an unnecessary Effect, and they add complexity when used without a demonstrated need. React’s guidance is explicit: “You should only rely on useMemo as a performance optimization. If your code doesn’t work without it, find the underlying problem and fix it first. Then you may add useMemo to improve performance.” See the useMemo reference and useCallback reference.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Should you use React Compiler?

React Compiler can automate many memoization optimizations, including work aimed at cascading re-renders and expensive calculations in components and Hooks. It is optional; whether it is a fit depends on whether the project enables it, supports its build integration, and follows the Rules of React. Consult the current React Compiler introduction for setup and status.

During adoption, check what the compiler already optimizes and test changes carefully. Existing manual memoization should not be removed wholesale: verify that the affected behavior and performance remain correct before simplifying it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the fix by the cause

What the profile or update trace shows First approach to try What to verify
Redundant state or an Effect copying a value available during render Derive the value during render and remove the unnecessary update chain. The same interaction does less React render work and the UI stays correct.
A broad parent update reaches state-independent content Keep transient state closer to its users; consider passing stable JSX as children through a wrapper. The expensive subtree no longer does avoidable work on that interaction.
An expensive child renders from a parent despite unchanged inputs Try memo; simplify props or stabilize only the object or callback identity the boundary depends on. The props compare as intended, and the same measured interaction improves.
Repeated calculations or unstable identities remain costly after structural fixes Use targeted useMemo or useCallback, or assess React Compiler if the project supports it. Re-profile and retain only optimizations that help without making the code harder to reason about.

Re-profile before calling it fixed

After making one focused change, repeat the same interaction and compare the Profiler results. A lower render count alone is not proof of a better experience; look for reduced costly work and confirm the interface still behaves correctly. If the profile does not improve, remove an unnecessary optimization and investigate other sources of delay rather than layering on more memoization.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.