React Interview Questions

React Interview Questions - Performance & Optimization (91-120)

Master React performance for FAANG interviews: React.memo, useMemo, useCallback, virtualization, code splitting, and more with practical examples.

By TechCoder TeamLast updated: 2026-06-15
In a Nutshell

Master React performance for FAANG interviews: React.memo, useMemo, useCallback, virtualization, code splitting, and more with practical examples. This interview-focused guide covers essential react interview questions - performance & optimization (91-120) concepts for technical interviews.

React Interview Questions - Performance & Optimization (91-120)

Performance is crucial for providing great user experiences. FAANG interviewers love asking about performance optimization!

Question 91: Why optimize React performance?

  • Faster initial load time
  • Better user experience
  • Reduced server costs (less bandwidth)
  • Higher SEO ranking
  • Better mobile performance

Question 92: What are common React performance issues?

  1. Unnecessary re-renders
  2. Large bundle sizes
  3. Expensive DOM operations
  4. Poorly optimized lists/grids
  5. Too many API calls

Question 93: How to prevent unnecessary re-renders?

  1. Use React.memo (for components)
  2. Use useCallback (for functions)
  3. Use useMemo (for values/expensive calculations)
  4. Avoid passing new objects/arrays as props
  5. Normalize state shape
  6. Use state lifting carefully

Question 94: React.memo in depth

React.memo is a higher-order component (HOC) that memoizes a component. It does a shallow comparison of props and skips re-renders if props haven't changed.

Example:

import { memo } from 'react';

// Memoized component - only re-renders if props change
const MemoizedTodoList = memo(function TodoList({ todos, onDelete }) {
  console.log('TodoList rendered');
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id} onClick={() => onDelete(todo.id)}>
          {todo.text}
        </li>
      ))}
    </ul>
  );
});

Question 95: Shallow comparison in React

Shallow comparison checks if primitive values are equal, and if objects/arrays have the same references.

What it checks:

  • Primitives (numbers, strings, booleans): Value comparison
  • Objects/arrays: Reference comparison

Question 96: useMemo in depth

useMemo memoizes the result of an expensive calculation, so it doesn't recalculate on every render.

Example:

import { useMemo } from 'react';

function ProductList({ products, filter }) {
  // Expensive calculation: Filter products
  const filteredProducts = useMemo(() => {
    console.log('Filtering products...');
    return products.filter(product =>
      product.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [products, filter]); // Only recalculate when these change
  
  return <ul>{filteredProducts.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}

Question 97: useCallback in depth

useCallback memoizes a function reference, preventing unnecessary re-renders of child components that depend on it.

Example:

import { useState, useCallback } from 'react';

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  // Memoize handleClick
  const handleClick = useCallback(() => setCount(c => c + 1), []);
  
  return (
    <div>
      <MemoizedButton onClick={handleClick}>Count: {count}</MemoizedButton>
      <input value={text} onChange={(e) => setText(e.target.value)} />
    </div>
  );
}

const MemoizedButton = memo(({ onClick, children }) => {
  console.log('Button rendered');
  return <button onClick={onClick}>{children}</button>;
});

Question 98: What is virtualization/windowing?

Virtualization renders only the visible items in a large list/grid, drastically improving performance for long lists.

  • react-window (smaller, simpler)
  • react-virtualized (more features)

Question 99: react-window example

import { FixedSizeList as List } from 'react-window';

const items = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);

function LongList() {
  const Row = ({ index, style }) => (
    <div style={style}>{items[index]}</div>
  );

  return (
    <List
      height={500} // Visible height
      itemCount={items.length}
      itemSize={35} // Height per item
      width={300}
    >
      {Row}
    </List>
  );
}

Question 100: What is code splitting?

Code splitting splits your bundle into smaller chunks that are loaded on demand, reducing initial load time.


Question 101: React.lazy and Suspense

import { lazy, Suspense } from 'react';

// Lazy load component (dynamic import)
const LazyComponent = lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <h1>My App</h1>
      {/* Show loading spinner while chunk loads */}
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </Suspense>
    </div>
  );
}

Question 102: Route-based code splitting

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { lazy, Suspense } from 'react';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));

function App() {
  return (
    <Router>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Suspense>
    </Router>
  );
}

Question 103: What are React DevTools Profiler?

React DevTools Profiler helps you:

  • See which components re-render
  • See how long renders take
  • Find performance bottlenecks

Question 104: What is useTransition?

useTransition lets you mark some state updates as non-urgent, so they don't block urgent updates like typing or scrolling.


Question 105: What is useDeferredValue?

useDeferredValue defers updating a non-urgent part of the UI, allowing urgent updates to run first.


Question 106: What is memoization?

Memoization is an optimization technique where you cache the results of expensive function calls and return the cached result when the same inputs occur again.


Question 107: What is the key prop for performance?

Using stable, unique keys helps React efficiently identify changes in lists, reducing unnecessary re-renders.

Don't use index as key if the list can change!


Question 108: How to optimize large forms?

  1. Use React Hook Form (more performant than Formik)
  2. Virtualize long forms with many fields
  3. Avoid unnecessary re-renders of form fields

Question 109: What is the purpose of useMemo with expensive calculations?

It prevents recalculating the same expensive value on every render.


Question 110: How to optimize image loading?

  1. Use modern image formats (WebP, AVIF)
  2. Compress images
  3. Lazy load images
  4. Use responsive images (srcset)
  5. Use next/image in Next.js

Question 111: Image lazy loading example

<img
  src="large-image.jpg"
  loading="lazy" // Native lazy loading
  alt="..."
  width={600}
  height={400}
/>

Question 112: What are server components in Next.js?

Server components let you write components that render on the server, reducing client-side JavaScript bundle size.


Question 113: What is React Server Components (RSC)?

RSC is a new architecture that lets you choose between:

  1. Server Components: Rendered on server, no client-side JS
  2. Client Components: "use client" - render on client, have state/lifecycle

Question 114: How to optimize bundle size?

  1. Code splitting
  2. Tree shaking
  3. Analyze bundle with webpack-bundle-analyzer
  4. Replace large libraries with smaller alternatives
  5. Use dynamic imports
  6. Compress (gzip/brotli)

Question 115: What is tree shaking?

Tree shaking removes unused code (dead code) from your bundle. It's enabled by default in modern bundlers like Webpack and Rollup.


Question 116: What is the React Profiler API?

The Profiler component measures how often your application renders and what the "cost" of rendering is.

Example:

import { Profiler } from 'react';

function onRenderCallback(
  id,
  phase,
  actualDuration,
  baseDuration,
  startTime,
  commitTime,
  interactions
) {
  console.log('Render:', id, 'took', actualDuration, 'ms');
}

function App() {
  return (
    <Profiler id="App" onRender={onRenderCallback}>
      <MyApplication />
    </Profiler>
  );
}

Question 117: What is the difference between actualDuration and baseDuration?

  • actualDuration: Time spent rendering the subtree including memoized components
  • baseDuration: Time it would take to render the entire subtree without memoization

Question 118: Should you use memo everywhere?

No! Memoization has a cost. Only use it when:

  1. The component renders often
  2. It renders with the same props
  3. It's expensive to render

Question 119: What is the cost of memoization?

Memoization takes:

  • Memory to store the memoized values
  • Time to compare previous and current props/inputs

Question 120: What is the best way to optimize list rendering?

Use virtualization/windowing (react-window or react-virtualized) for long lists, and ensure proper key usage!