Why does this list get slower as it grows?
A table that is instant with fifty rows crawls with five thousand. Nothing about the code changed, only the value of n.
- Level
- ENGINEER
- Read time
- 09 min
- Experiment
- Available
- Type
- MEASUREMENT
The question
Why does a lookup written inside a render loop turn a linear list into a quadratic one, and when does that actually matter in a browser?
Hypothesis
A lookup that scans the array is O(n). Performing it once per row makes the whole render O(n²). Indexing the data once turns the per-row cost into a constant.
Method
Laboratory available
The instrument for this investigation runs in the laboratory, where the controls, the live model and the observation log share one workstation.
Enter the laboratoryThe bench builds real arrays at the size you choose and runs each strategy on your device. The timings are measurements, not estimates.
What we observed
At small n every strategy looks fine, which is exactly why the problem ships. The scan and the index separate as n grows, and the pairwise comparison leaves the frame budget long before the others are noticeable.
{rows.map((row) => { // runs once per row, and scans every user each time const owner = users.find((user) => user.id === row.ownerId); return <Row key={row.id} row={row} owner={owner} />;})}const usersById = useMemo( () => new Map(users.map((user) => [user.id, user])), [users],);{rows.map((row) => ( <Row key={row.id} row={row} owner={usersById.get(row.ownerId)} />))}Why it happens
Complexity describes how cost grows, not how large it is. O(n²) with a tiny constant can beat O(n) with an expensive one at realistic sizes, which is why an array scan wins for a handful of items and loses badly at a thousand.
| n | Array scan | Map lookups |
|---|---|---|
| 100 | ~20,000 | ~500 |
| 1,000 | ~200,000 | ~1,400 |
| 10,000 | ~2,000,000 | ~10,400 |
Further research
Measure before rewriting. The profiler tells you which term dominates: a flat profile across thousands of small calls points at the algorithm, while a single long call points at one expensive operation. Optimising the wrong term is how a codebase accumulates clever code that changes nothing.
References
- 01MDNMap
- 02web.devVirtualize large lists