Performance: Client-side error boundaries
Client-side error boundaries affect interaction responsiveness and visual stability by catching runtime errors without crashing the whole app.
Jump into concepts and practice - no test required
import React from 'react'; class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { // You can also log the error to an error reporting service here } render() { if (this.state.hasError) { return <div role="alert">Something went wrong.</div>; } return this.props.children; } } function MyComponent() { return ( <ErrorBoundary> <ComponentThatMayThrow /> </ErrorBoundary> ); }
function MyComponent() { // No error boundary const data = JSON.parse('invalid json'); return <div>{data.name}</div>; }
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| No error boundary (app crash) | Full tree unmount | Multiple reflows due to remount | High paint cost for blank screen and reload | [X] Bad |
| Error boundary with fallback UI | Partial DOM update | Single reflow for fallback render | Low paint cost with stable UI | [OK] Good |
function ErrorBoundary({ children }) {
try {
return children;
} catch {
return <div>Error occurred</div>;
}
}
function BuggyComponent() {
throw new Error('Bug!');
}
export default function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}function ErrorBoundary({ children }) {
try {
return children;
} catch (error) {
console.log(error);
}
}
export default function App() {
return (
<ErrorBoundary>
<div>Hello</div>
</ErrorBoundary>
);
}