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.