Prefetching
Problem
Users click into detail pages and wait while data fetches from scratch every time. Common navigation paths like viewing orders or profiles always trigger loading states. Users see spinners for data that could have loaded proactively during idle time. The app feels reactive instead of anticipatory, creating unnecessary friction.
Solution
Load data or resources before they’re needed based on likely next actions. This makes navigation feel instant by having content ready before users ask for it.
Example
This example demonstrates prefetching product data when users hover over a link, so the data is ready instantly when they click.
function ProductCard({ id }) {
const prefetchProduct = () => {
// Start loading product data during hover (before click)
queryClient.prefetchQuery(['product', id], () =>
fetch(`/api/products/${id}`).then(r => r.json())
);
};
// Trigger prefetch on hover to have data ready for navigation
return <Link to={`/products/${id}`} onMouseEnter={prefetchProduct}>View</Link>;
}
Benefits
- Makes navigation feel instant by having content ready before users click.
- Improves perceived performance by using idle time productively.
- Reduces or eliminates loading spinners for common navigation paths.
- Creates a more responsive, anticipatory user experience.
Tradeoffs
- Wastes bandwidth if predictions are wrong and prefetched data is never used.
- Can slow down current page if prefetching competes for resources.
- Requires careful tuning to predict which data users are likely to need.
- May prefetch stale data if content changes between prefetch and actual navigation.