Volume 9

Q384: Performance Refactor Drill Reducing Render Cost Without Breaking Behavior

Difficulty: SeniorFrequency: HighAnswer time: 20-25 minutes

What Interviewers Want To Evaluate

This drill tests whether you can improve React performance without guessing.

Senior frontend engineers measure first, identify the bottleneck, choose the smallest effective fix, and verify that behavior still works.

The interviewer wants to see whether you understand render cost, state placement, memoization, list size, derived data, and user-facing metrics.

Short Interview Answer

For a performance refactor, I first reproduce the slow interaction and measure whether the cost is rendering, JavaScript work, layout, network, or data processing. If it is React render cost, I inspect state ownership, expensive derived calculations, unstable props, large lists, and unnecessary subscriptions. Then I apply targeted fixes such as state colocation, memoized selectors, virtualization, deferred rendering, or splitting components, and verify with profiling and tests.

First Rule

Do not start with useMemo.

Start with:

what is slow
for whom
on which device
after which action
with what data size

Performance work needs a target.

Without a target, optimization becomes folklore.

Measurement Tools

Use:

React DevTools Profiler
browser Performance panel
console timing for local experiments
Web Vitals
field monitoring
network waterfall
bundle analyzer

Choose the tool based on the symptom.

A slow click is not debugged the same way as a slow first load.

Common Render Costs

Look for:

state too high in the tree
large children rerendering
derived arrays recreated every render
unstable object and function props
context value changing too often
large lists without virtualization
expensive formatting in render
controlled inputs tied to heavy siblings

Render performance is often about ownership boundaries.

Example Problem

A dashboard search input feels laggy.

Possible cause:

every keystroke updates parent dashboard state
parent rerenders charts table filters and summary cards
large table recomputes filtered rows

Potential fix:

keep draft input state local
debounce committed query
memoize filtered rows by data and query
virtualize table rows
defer expensive result rendering

Each fix maps to a measured cost.

State Colocation

Move state closer to where it is used when:

parent rerenders are expensive
siblings do not need the state
state is transient
state changes frequently

Do not colocate state if:

URL needs it
server fetch depends on it
multiple branches need it
parent owns the workflow

State placement is a product architecture decision.

Memoization

Memoization helps when:

calculation is expensive
inputs are stable
saved work is meaningful
memo cost is lower than recomputation

Memoization hurts when:

calculation is trivial
dependencies change every render
it hides state design problems
it makes code harder to read

Use memoization as a tool, not a ritual.

List Performance

For large lists:

stable keys
pagination
server-side filtering
virtualization
windowing
row memoization only when useful
avoid measuring every row repeatedly

Virtualization improves rendering cost but adds accessibility and scroll behavior complexity.

Mention the trade-off.

React Transitions

Use transitions when:

urgent input updates should stay responsive
expensive results can lag slightly
navigation or filtering has non-urgent rendering

The user should keep typing smoothly while results update.

This is especially useful for search and filtering experiences.

Verification

After the refactor:

profile the same interaction
compare render count
compare duration
test behavior
check accessibility
check low-end simulation
check no stale data bug was introduced

Performance fixes can break correctness.

The verification step protects both.

Common Mistakes

  • Optimizing without measuring.
  • Adding React.memo everywhere.
  • Keeping frequent state too high.
  • Ignoring context rerender boundaries.
  • Sorting or filtering large arrays in render without thought.
  • Virtualizing small lists unnecessarily.
  • Improving desktop while mobile remains slow.
  • Breaking keyboard or screen reader behavior during optimization.

Final Mental Model

Performance refactoring is:

measure
locate cost
choose smallest fix
preserve behavior
verify user impact

Good performance work makes the interface feel calmer without making the code mysterious.