More on the topic...
Generating detailed summary...
Failed to generate summary. Please try again.
Single-page apps sped up navigation by rendering new screens instantly, but they forced us to patch empty layouts with spinners, skeletons, shimmer effects and fallbacks. Browsers used to handle waiting at the page level—click a link, wait for the server, then render a complete page. We lost that simple model when we shifted data fetching into each component. Now every route change demands its own loading logic.
Route transitions bring back the old model inside modern routers. Instead of loading data after rendering, you tell the router what each route needs up front. TanStack Router’s loader API, for example, lets you call ensureQueryData before committing navigation. You can even start that fetch on link hover or when a link appears in view. When the user finally clicks, the next page is already populated—or the router holds off the transition until it is.
The real advantage shows up in development. If part of your new page flashes in late, you know you forgot to preload that data. Empty UI becomes a diagnostic flag rather than a production hiccup hidden by a skeleton. And when data truly takes too long, you replace scattered spinners with a single global indicator—think GitHub’s top-of-the-page progress bar—triggered by the router’s transition state and delayed a few hundred milliseconds so brief waits stay invisible.
This shifts work from endless component-level loading states into strategic preloading and a unified fallback. Queries simply return data or nothing; no more layered shimmers. Gaps in the interface during testing force you to improve your preload strategy until waiting states disappear almost entirely.
Questions about this article
No questions yet.