Skip to content
Optimal Lab

Frontend · interactive

Memoisation: memo, useMemo, useCallback

Typing in a search box re-renders its parent, and by default every child too, including a chart that takes 45 ms to render. Typing “lamps” shows where the time goes.

function Page() {
  const [q, setQ] = useState("");
  return <>
    <input value={q} onChange={e => setQ(e.target.value)} />
    <Chart data={data} onSelect={(p) => open(p)} />
  </>;
}
  • “l”47 ms
  • “a”47 ms
  • “m”47 ms
  • “p”47 ms
  • “s”47 ms

Green: input. Red: chart re-render. Over 16 ms per keystroke feels laggy.

235 ms of rendering for 5 keystrokes

Every keystroke re-renders the chart even though its data didn't change.

Optimisation

Step 1 of 4

  1. 1

    Parents re-render children

    By default a component re-renders whenever its parent does, props changed or not.

    Usually cheap; sometimes not.

  2. 2

    memo compares props

    A memoised component skips rendering when every prop is equal by reference.

    Objects and functions are new each render.

  3. 3

    useCallback and useMemo

    Keep the same function or computed value across renders until their dependencies change.

    Otherwise memo is wasted work.

  4. 4

    Measure, or move state down

    Profile before memoising. Often it's simpler to move the search state into its own component so the chart's parent never re-renders.

    The React Compiler automates much of this.

In production

Tools and technologies

React apps memoise to skip expensive re-renders.

Not tied to one language — use these names when you search docs or design a system.