Bird
Raised Fist0
NextJSframework~8 mins

Why error boundaries matter in NextJS - Performance Evidence

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: Why error boundaries matter
MEDIUM IMPACT
Error boundaries affect user experience by preventing full app crashes and reducing layout shifts caused by unhandled errors.
Handling runtime errors in React components to avoid app crashes
NextJS
import { ErrorBoundary } from 'react-error-boundary';

function ErrorFallback() {
  return <div role="alert">Something went wrong.</div>;
}

function MyComponent() {
  const data = JSON.parse('invalid json');
  return <div>{data.name}</div>;
}

export default function App() {
  return (
    <ErrorBoundary FallbackComponent={ErrorFallback}>
      <MyComponent />
    </ErrorBoundary>
  );
}
Error boundaries catch errors and render fallback UI, preventing full app crashes and layout shifts.
📈 Performance GainAvoids full tree unmount, reduces CLS, and improves perceived stability.
Handling runtime errors in React components to avoid app crashes
NextJS
function MyComponent() {
  // No error boundary
  const data = JSON.parse('invalid json'); // throws error
  return <div>{data.name}</div>;
}
Without error boundaries, errors cause the entire React tree to unmount, leading to blank screens and layout shifts.
📉 Performance CostTriggers full component tree unmount and re-render, causing CLS and poor user experience.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
No error boundary, error crashes appFull tree unmount and remountMultiple reflows due to layout shiftsHigh paint cost from blank screen and re-render[X] Bad
Error boundary with fallback UIOnly fallback UI renderedSingle reflow, minimal layout shiftLow paint cost, stable UI[OK] Good
Rendering Pipeline
Error boundaries intercept errors during rendering or lifecycle methods, preventing React from unmounting the entire component tree and triggering costly reflows or layout shifts.
JavaScript Execution
Layout
Paint
⚠️ BottleneckLayout due to full tree unmount and re-render on unhandled errors
Core Web Vital Affected
CLS
Error boundaries affect user experience by preventing full app crashes and reducing layout shifts caused by unhandled errors.
Optimization Tips
1Always wrap components that may throw errors with error boundaries to prevent full app crashes.
2Use fallback UI in error boundaries to maintain visual stability and reduce layout shifts.
3Error boundaries improve CLS by isolating errors and avoiding full tree unmounts.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance benefit of using error boundaries in a React or Next.js app?
AThey reduce the size of the JavaScript bundle sent to the browser.
BThey improve JavaScript execution speed by optimizing code.
CThey prevent full app crashes and reduce layout shifts caused by errors.
DThey eliminate the need for server-side rendering.
DevTools: Performance
How to check: Record a session where an error occurs without an error boundary, then with one. Compare layout shifts and paint times.
What to look for: Look for large layout shifts (CLS spikes) and long paint durations when errors are unhandled versus stable fallback rendering.

Practice

(1/5)
1. What is the main purpose of error boundaries in a Next.js application?
easy
A. To catch JavaScript errors in components and display a fallback UI
B. To improve SEO by optimizing page metadata
C. To handle server-side rendering errors automatically
D. To manage user authentication and sessions

Solution

  1. Step 1: Understand error boundaries role

    Error boundaries catch errors in React components during rendering, lifecycle methods, and constructors.
  2. Step 2: Identify their main benefit

    They prevent the whole app from crashing by showing a fallback UI instead of a broken screen.
  3. Final Answer:

    To catch JavaScript errors in components and display a fallback UI -> Option A
  4. Quick Check:

    Error boundaries catch errors = B [OK]
Hint: Error boundaries catch errors and show fallback UI [OK]
Common Mistakes:
  • Confusing error boundaries with authentication
  • Thinking error boundaries improve SEO
  • Assuming error boundaries handle server errors automatically
2. Which of the following is the correct way to define an error boundary component in Next.js using React functional components?
easy
A. class ErrorBoundary extends React.Component { constructor() { super(); this.state = { hasError: false }; } componentDidCatch() { this.setState({ hasError: true }); } render() { if (this.state.hasError) return
Error occurred
; return this.props.children; } }
B. function ErrorBoundary({ children }) { const [hasError, setHasError] = React.useState(false); if (hasError) return
Error
; return children; }
C. function ErrorBoundary({ children }) { try { return children; } catch { return
Error
; } }
D. class ErrorBoundary extends React.Component { state = { error: null }; render() { if (this.state.error) return
Error
; return this.props.children; } }

Solution

  1. Step 1: Recall error boundary implementation

    Error boundaries must be class components with lifecycle methods like componentDidCatch to catch errors.
  2. Step 2: Check options for correct syntax

    class ErrorBoundary extends React.Component { constructor() { super(); this.state = { hasError: false }; } componentDidCatch() { this.setState({ hasError: true }); } render() { if (this.state.hasError) return <div>Error occurred</div>; return this.props.children; } } correctly defines a class component with constructor, state, componentDidCatch, and render method.
  3. Final Answer:

    class ErrorBoundary extends React.Component { constructor() { super(); this.state = { hasError: false }; } componentDidCatch() { this.setState({ hasError: true }); } render() { if (this.state.hasError) return <div>Error occurred</div>; return this.props.children; } } -> Option A
  4. Quick Check:

    Error boundaries require class + componentDidCatch = C [OK]
Hint: Error boundaries must be class components with componentDidCatch [OK]
Common Mistakes:
  • Trying to create error boundaries as functional components
  • Missing componentDidCatch lifecycle method
  • Not initializing state to track errors
3. Given the following error boundary component and a child component that throws an error, what will be rendered?
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  componentDidCatch(error, info) {
    this.setState({ hasError: true });
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

function BuggyComponent() {
  throw new Error('Bug!');
  return <div>No bugs</div>;
}

// Usage
<ErrorBoundary>
  <BuggyComponent />
</ErrorBoundary>
medium
A. Uncaught Error: Bug!
B. No bugs
C.

Something went wrong.

D. Blank screen

Solution

  1. Step 1: Understand error throwing in child

    BuggyComponent throws an error immediately when rendered.
  2. Step 2: Check error boundary response

    ErrorBoundary catches the error in componentDidCatch and sets hasError to true, rendering fallback UI.
  3. Final Answer:

    <h1>Something went wrong.</h1> -> Option C
  4. Quick Check:

    Error caught, fallback UI shown = A [OK]
Hint: ErrorBoundary shows fallback UI when child throws error [OK]
Common Mistakes:
  • Expecting child component output despite error
  • Thinking error is uncaught and crashes app
  • Assuming blank screen instead of fallback UI
4. You have this error boundary component but it does not catch errors as expected. What is the likely problem?
function ErrorBoundary({ children }) {
  try {
    return children;
  } catch (error) {
    return <div>Error occurred</div>;
  }
}
medium
A. Try-catch works fine for error boundaries in functional components
B. Error boundaries must be class components with componentDidCatch method
C. You forgot to wrap children in a React.Fragment
D. You need to use useErrorBoundary hook instead

Solution

  1. Step 1: Analyze error boundary implementation

    Try-catch inside a functional component does not catch errors during rendering lifecycle in React.
  2. Step 2: Recall React error boundary requirements

    Error boundaries must be class components implementing componentDidCatch lifecycle method to catch errors properly.
  3. Final Answer:

    Error boundaries must be class components with componentDidCatch method -> Option B
  4. Quick Check:

    Functional try-catch won't catch render errors = A [OK]
Hint: Error boundaries require class + componentDidCatch, not try-catch [OK]
Common Mistakes:
  • Using try-catch in functional components expecting error boundary behavior
  • Assuming React has a useErrorBoundary hook
  • Thinking wrapping children in fragments fixes error catching
5. You want to add a reset button in your error boundary to let users try again after an error. Which approach correctly implements this behavior?
hard
A. Use a useEffect hook to reset error state automatically after 5 seconds
B. Reload the entire page using window.location.reload() when the button is clicked
C. Wrap the reset button in a try-catch block to prevent errors
D. Add a button that calls this.setState({ hasError: false }) inside the error boundary's fallback UI

Solution

  1. Step 1: Understand reset behavior in error boundaries

    Resetting error state allows the component tree to re-render normally after an error.
  2. Step 2: Identify correct reset method

    Calling this.setState({ hasError: false }) inside the error boundary resets the error state and shows children again.
  3. Final Answer:

    Add a button that calls this.setState({ hasError: false }) inside the error boundary's fallback UI -> Option D
  4. Quick Check:

    Reset error state with setState = D [OK]
Hint: Reset error by setting hasError false in state [OK]
Common Mistakes:
  • Reloading page instead of resetting state
  • Using try-catch around reset button unnecessarily
  • Relying on automatic reset with useEffect without user action