React Suspense lets you declaratively specify loading states for components that are waiting for data or code to load.
Basic Usage#
Code Splitting with lazy()#
Nested Suspense Boundaries#
Data Fetching with Suspense#
Suspense with Error Boundaries#
Loading States and Skeletons#
SuspenseList (Experimental)#
useTransition for Non-Blocking Updates#
useDeferredValue#
Server Components with Suspense#
Custom Suspense-Compatible Resources#
Loading Priority Patterns#
Best Practices#
Boundary Placement:
✓ Place at route level for pages
✓ Use nested boundaries for sections
✓ Match skeletons to component structure
✓ Consider user experience
Loading States:
✓ Use meaningful skeletons
✓ Avoid layout shifts
✓ Show progress when possible
✓ Keep fallbacks lightweight
Performance:
✓ Preload critical resources
✓ Use useTransition for navigation
✓ Defer non-critical updates
✓ Code split by routes
Avoid:
✗ Too many suspense boundaries
✗ Flashing loading states
✗ Blocking critical content
✗ Forgetting error boundaries
Conclusion#
React Suspense provides declarative loading states for async operations. Use it with lazy() for code splitting, with data fetching libraries for loading states, and with useTransition for smooth transitions. Place Suspense boundaries strategically to control loading experiences. Combine with Error Boundaries for comprehensive async handling. Match skeleton components to actual content structure to prevent layout shifts and provide better user experience.