Skip to content

Performance Optimization Interview Questions for React JS

25 Performance Optimization questions with answers for react js roles — 5 easy, 11 medium, 9 hard.

About Performance Optimization

Interviewers for mid and senior roles expect you to find and fix slow screens. Learn React.memo and the React Compiler, code splitting with lazy and Suspense, profiling, list virtualisation, bundle analysis, Core Web Vitals such as LCP and INP, image optimisation, memory leaks, Web Workers and when memoisation is not worth it.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What does React.memo do?

Save to ▾
Show answer
React.memo wraps a component so React skips re-rendering it when its props are shallowly equal to the previous props. It is useful for components that render often with the same props and are expensive to render, like rows in a big table. It only works if props stay referentially stable, so objects and callbacks passed to it are usually memoised with useMemo and useCallback.
02

How do you implement code splitting with React.lazy and Suspense?

Save to ▾
Show answer
Load a component only when it is needed with a dynamic import. import { lazy, Suspense } from 'react'; const Reports = lazy(() => import('./Reports')); function App() { return ( <Suspense fallback={<Spinner />}> {showReports && <Reports />} </Suspense> ); } The bundler creates a separate chunk for Reports, reducing the initial JavaScript download.
03

How do you optimise images in a React app?

Save to ▾
Show answer
Serve modern formats like WebP or AVIF, resize images to their display size and use srcset with sizes for responsive images. Add loading="lazy" for images below the fold and fetchpriority="high" for the main hero image. Always set width and height or aspect-ratio to prevent layout shift. In Next.js, the next/image component automates resizing, formats and lazy loading.
04

A developer says the app is too slow, based on testing it with the development server. What do you tell them?

Save to ▾
Show answer
The development build includes extra warnings, StrictMode double rendering, checks and unminified code, so it is much slower and can mislead you. Production builds created with npm run build are minified, tree-shaken and optimised. Test performance on the production build, ideally on a mid-range Android phone with throttled network, because many Indian users browse on such devices and slower connections.
05

Tell me about a mistake you made that reached production and what you learned.

Save to ▾
Show answer
Situation: I removed what looked like an unused prop in a shared Button component. Task: after release, the payment page's disabled state broke. Action: I owned it immediately, rolled back, then fixed it and added a test plus a TypeScript type so the prop could not be removed silently. Result: the issue was live for under an hour, and I now search all usages and rely on types before deleting code.
06

What is the React Compiler?

Save to ▾
Show answer
The React Compiler, released as stable version 1.0 in late 2025, is a build-time tool (Babel plugin, also integrated in Vite and Next.js setups) that automatically memoises components and values. It analyses your code and inserts caching similar to useMemo, useCallback and React.memo, so developers write plain code. It requires following the rules of React, such as pure rendering, and can be adopted gradually per directory.
07

How do you find what is making a React page slow?

Save to ▾
Show answer
Use the React DevTools Profiler: record an interaction, then check the flame chart for components with long render times and the reason each one re-rendered (enable 'record why each component rendered'). Pair it with the Chrome Performance panel for long tasks, layout and network. Enable highlight updates to spot unnecessary renders. Measure first, fix the biggest cost, then measure again in a production build.
08

What is list virtualisation?

Save to ▾
Show answer
Virtualisation, or windowing, renders only the rows visible in the viewport plus a small buffer, instead of thousands of DOM nodes. As the user scrolls, rows are recycled with new data. Libraries such as TanStack Virtual and react-window implement it. It dramatically cuts render time and memory for long lists, chat histories and data grids, but needs care with variable row heights and browser find-in-page.
09

An orders table renders 10,000 rows and the page freezes on load and scroll. What would you do?

Save to ▾
Show answer
First question whether users need all rows at once: server-side pagination or infinite scroll with cursor-based loading may solve it. If a long scrollable list is required, virtualise it with TanStack Virtual so only around 30 rows exist in the DOM. Also memoise row components, avoid heavy formatting in render by precomputing, and move sorting or filtering off the main thread if it is expensive.
10

You wrapped a row component in React.memo, but the profiler shows it still re-renders every time. The parent passes onClick={() => remove(id)}. Why?

Save to ▾
Show answer
An inline function like onClick={() => remove(id)} creates a new function object on every render. React.memo compares props by reference, sees a different function and re-renders the child every time, so memo has no effect. Wrap the handler with useCallback and correct dependencies, or let the React Compiler handle it. If the child is not memoised, inline functions are fine and cheap.
11

How do you analyse and reduce JavaScript bundle size?

Save to ▾
Show answer
Generate a visual report with rollup-plugin-visualizer in Vite or @next/bundle-analyzer in Next.js. Look for large dependencies, duplicate packages and code that loads on every page. Fixes include importing only what you need, replacing heavy libraries such as moment with date-fns or dayjs, lazy loading routes and rarely used components, and checking that libraries support tree shaking. Track size in CI to prevent regressions.
12

What are Core Web Vitals and how do React apps affect them?

Save to ▾
Show answer
Core Web Vitals are Google's user experience metrics: LCP (Largest Contentful Paint, loading, target under 2.5s), INP (Interaction to Next Paint, responsiveness, under 200ms, which replaced FID in 2024) and CLS (Cumulative Layout Shift, visual stability, under 0.1). Large React bundles hurt LCP and INP, heavy renders on clicks hurt INP, and images or content without reserved space hurt CLS. SSR, code splitting and transitions help.
13

What is tree shaking?

Save to ▾
Show answer
Tree shaking is dead code elimination done by bundlers like Rollup (used by Vite), esbuild and webpack. They analyse ES module import and export statements and drop exports that are never used. It works only with static ESM syntax, not CommonJS require, and can be blocked by modules with side effects. Importing import { debounce } from 'lodash-es' instead of the whole lodash library keeps the bundle small.
14

A developer writes key={Math.random()} to silence the missing key warning. What problem does this create?

Save to ▾
Show answer
A new random key on every render tells React each item is brand new, so it unmounts and remounts every row each time. This destroys component state such as typed input and focus, re-runs effects and is very slow for large lists. Keys must be stable and unique, ideally an id from the data. If items have no id, generate ids once when the data is created.
15

Tell me about a time you improved the performance of an application.

Save to ▾
Show answer
Situation: our admin dashboard took about eight seconds to become usable on office laptops. Task: bring it under three seconds. Action: I profiled it, found a 2 MB bundle and a chart library loaded on every page, lazy loaded routes and charts, replaced moment with dayjs and virtualised a large table. Result: load time dropped to around 2.5 seconds and support complaints about slowness stopped.
16

How do you handle a tight deadline when you know the code is not perfect?

Save to ▾
Show answer
Situation: a festive sale banner feature had to go live in two days. Task: ship safely without gold-plating. Action: I listed must-haves with the product owner, wrote tests for the critical checkout path, kept a simple implementation and logged clear tech-debt tickets for refactoring. Result: we launched on time with no incidents, and I cleaned up the code in the next sprint as planned.
17

Typing in a search box feels laggy because a big product list is filtered on every keystroke. How do you fix it?

Save to ▾
Show answer
Keep the input state urgent and make the expensive part deferred. Use const deferredQuery = useDeferredValue(query) and filter with deferredQuery inside useMemo, and wrap the list in React.memo. The input updates instantly while React renders the list in the background and can interrupt it. If filtering is still heavy, debounce it, move it to a Web Worker or filter on the server.
18

A teammate wraps every function in useCallback and every value in useMemo for performance. When should you not memoise, and what feedback would you give?

Save to ▾
Show answer
Memoisation has costs: extra memory, comparisons on every render and more complex code. Skip it for cheap calculations, components that rarely re-render, and props that change every render anyway. Memoising everything by default also hides design problems like state placed too high. Use the profiler to find real bottlenecks first. With the React Compiler, manual memoisation is mostly needed only as an escape hatch.
19

Without using memo, what structural techniques reduce unnecessary re-renders?

Save to ▾
Show answer
Move state down into the smallest component that needs it, so changes do not re-render siblings. Lift content up by passing expensive parts as children: a component that changes state does not re-render JSX it receives as children, because that JSX was created by the parent. Split large components, and avoid putting fast-changing values in widely used context. These often fix performance more cleanly than memoisation.
20

After navigating between pages for a while, the app's memory keeps growing and it slows down. How do you investigate a memory leak?

Save to ▾
Show answer
Take heap snapshots in Chrome DevTools Memory panel before and after repeated navigation and compare retained objects, especially detached DOM nodes. Common React causes are effects without cleanup: intervals, event listeners on window, WebSocket subscriptions and third-party chart instances not destroyed. Also check global caches growing without limits. Add cleanups in useEffect returns and verify the heap stabilises.
21

When would you use a Web Worker in a React application?

Save to ▾
Show answer
Use a Web Worker for CPU-heavy work that would block the main thread, such as parsing a large CSV, image processing, complex calculations or searching big datasets in the browser. The worker runs in a separate thread and communicates through postMessage, so the UI stays responsive. Libraries like Comlink simplify the messaging. Workers cannot touch the DOM, so results are sent back and set in state.
22

How do Suspense and streaming server rendering improve performance?

Save to ▾
Show answer
With streaming SSR, the server sends HTML in chunks: the page shell is sent immediately and slower sections wrapped in Suspense are streamed later as their data resolves, replacing the fallback. Users see content sooner and hydration of parts can happen selectively, prioritising what the user interacts with. Frameworks like Next.js App Router use this with server components and loading.js boundaries.
23

What resource preloading APIs did React 19 add?

Save to ▾
Show answer
React 19 added functions in react-dom such as preload, preinit, prefetchDNS and preconnect. They tell the browser to load fonts, stylesheets, scripts or connect to API origins early, and React places the hints in the document head, including during server rendering. React 19 also supports rendering <title>, <meta> and <link> tags inside components, hoisting them to the head automatically.
24

Field data shows poor INP on the 'Add to cart' button of a product page. How do you improve it?

Save to ▾
Show answer
Profile the click to see what runs. Typical problems are a large synchronous re-render of the whole page, heavy analytics code and expensive state updates in the handler. Update the button feedback first and wrap the non-urgent part (cart drawer, recommendations) in startTransition, defer analytics with setTimeout or requestIdleCallback, narrow which components subscribe to cart state and break up long tasks.
25

After a release, the Lighthouse performance score of the home page dropped from 90 to 60. How do you find and fix the cause?

Save to ▾
Show answer
Compare the two builds instead of guessing. Run Lighthouse and WebPageTest on both versions, check which metric dropped (LCP, TBT or CLS), and diff bundle analyser reports to spot new heavy dependencies. Review the release changes: a new third-party script, an unoptimised hero image or a component moved from server to client are common causes. Fix it, then add a performance budget check in CI to prevent repeats.

Frequently asked questions

How important is Performance Optimization in React JS interviews?

Interviewers for mid and senior roles expect you to find and fix slow screens. Learn React.memo and the React Compiler, code splitting with lazy and Suspense, profiling, list virtualisation, bundle analysis, Core Web Vitals such as LCP and INP, image optimisation, memory leaks, Web Workers and when memoisation is not worth it.

How should I use the Performance Optimization sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.