Suspense, Error Boundaries & Resilient UI
Design loading boundaries, error recovery, lazy components, streaming-oriented UI concepts, and failure isolation.
Suspense Boundaries
Suspense lets a component tree declare a fallback while some child work is not ready under a supported Suspense-enabled mechanism. A boundary defines a user-visible loading region.
Good boundaries correspond to meaningful chunks of UI. A single application-wide spinner can hide useful content and make the interface feel blocked. Too many tiny boundaries can create distracting loading transitions.
Suspense is a coordination mechanism; it does not mean every asynchronous operation can automatically be placed inside a component and awaited.
<Suspense fallback={<ProfileSkeleton />}>
<ProfilePanel />
</Suspense>- Choose boundaries around meaningful UI regions.
- Fallbacks should preserve layout where possible.
- Suspense support depends on the data/loading mechanism being used.
Error Boundaries & Failure Isolation
An error boundary catches rendering errors in its descendant tree and displays fallback UI instead of allowing the entire application subtree to fail.
Error boundaries do not catch every kind of error. Event handler errors, asynchronous callbacks, server errors, and errors thrown outside the boundary's supported rendering lifecycle require other handling strategies.
Place boundaries around meaningful failure domains: a dashboard widget, route, editor, or application shell. A user should ideally be able to continue using unaffected parts of the application.
Treat errors as part of the UI design. Decide what can fail independently and give users a recovery path.
- Error boundaries isolate rendering failures.
- Different error sources require different handling mechanisms.
- Provide recovery rather than only displaying a stack trace.
Skeletons, Spinners & Perceived Performance
Loading UI should communicate the shape of incoming content. Skeletons can reduce layout shift and make the interface feel more responsive than a generic centered spinner.
Do not show loading indicators for extremely short operations if they create flicker. Conversely, do not hide long waits with no feedback.
Preserve stable dimensions when possible so content appearing later does not move interactive controls unexpectedly.
- Loading UI is part of product design.
- Skeletons can reduce layout shift.
- Avoid spinner flicker and unpredictable content movement.
Retry, Reset & Recovery
Recovery behavior should match the failure. A transient network failure may be retryable; a permission error requires authentication or authorization; invalid user input requires correction.
Resetting a failed subtree with a new key can be useful when local state has become inconsistent. Retrying should avoid creating infinite request loops and should provide feedback about the attempt.
Logging should capture enough context to diagnose the failure without exposing secrets or sensitive user data.
- Different failures need different recovery actions.
- Retries need limits and backoff where appropriate.
- Observability should be useful without leaking sensitive information.