next.js: [NEXT-1187] Link navigation with loading.tsx is not instant for dynamic pages
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 22.1.0: Sun Oct 9 20:14:30 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T8103
Binaries:
Node: 18.12.1
npm: 8.19.2
Yarn: 1.22.19
pnpm: N/A
Relevant packages:
next: 13.0.6-canary.2
eslint-config-next: 13.0.5
react: 18.2.0
react-dom: 18.2.0
Which area of Next.js is affected? (leave empty if unsure)
App directory (appDir: true), Routing (next/router, next/navigation, next/link)
Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster
https://github.com/tonypizzicato/next-13-loading
To Reproduce
- pull the repo
- run
yarn install && yarn dev
- open
localhost:3000
in the browser - go to the “Careers” page
- reload the page
- set some throttling in devtools
- click different pages in the menu
- notice that “Careers” page loading state and route change are done instantly but with some delay for other pages
Describe the Bug
When you have a dynamic page with loading.tsx
the route change and showing the loading animation are instant only for the page, which was freshly loaded. For other dynamic pages it hits the server first, then shows the loading state
https://user-images.githubusercontent.com/640122/204661070-b9409f71-3814-45e6-bf56-923cdf4e2fc6.mov
Expected Behavior
Instantly navigate to the desired dynamic page and show loading component
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 54
- Comments: 107 (46 by maintainers)
I think that the loading.tsx should be instant without any network calls. I know that the loading.tsx will be under a page request, but like @tonypizzicato said the website should prefetch the Links that are on the page. That’s the idea, from a user’s POV, the user should receive instant feedback from the app. If the loading.tsx will take some time to load (even a small one) it will be useless.
Hey, I think we identified the issue and will be rolling out a fix.
We are also experiencing this issue, and it is still present on v13.3.
The concept of “loading” for the end user means anything that is delaying their request, whether it’s due to server processing or network latency.
There should be no distinction to the end user on technical merit. This is purely a UX issue.
End users need immediate feedback, whether that’s the data they’ve requested or feedback to say their request is being handled.
Currently, this implementation fails to do this.
This is a core part of the age-old business arguement for retaining impatient users that we work ever so hard to get, that cannot be overlooked.
The fact that the on-request loading feedback needs loading on-request makes this implementation feel like one step forward and two steps back.
We are very grateful for NextJS and we do appreciate that the AppDir is still in beta, but please make sure this UX issue is fixed before release.
@huozhi @timneutkens
Can we re-open this issue? I’m on latest Next and this does definitely still appear to be an issue. The “instant” loading pages do appear to require a network roundtrip to display, and so would appear to be anything but “instant”
For a page without Suspense streaming, the loading component seems to show after a network roundtrip. For a page with Suspense streaming, it doesn’t seem to show at all, since the actual page is ready once that network roundtrip is complete, so the page with the Suspense fallback shows instead.
Am I wrong to assume these loading.tsx components will be loaded client-side, to show instantly on navigation?
Here’s a demo
The related repo is here: https://github.com/arackaf/next-instant-loading
which is deployed here: https://next-instant-loading.vercel.app/stream
@mhesham32 @rusted-love
After a little bit of time, i found out the problem with
Suspense
not showing 👉🏾 The culprit is vercel.I tested on different providers to validate my hypothesis :
Suspense
fallback is always shownSuspense
fallback is shown if it hadn’t been shown before but after it is never shown again, even if the request is slowed down (fake2s
delay)@cloudfare/next-on-pages
package) : theSuspense
fallback is always shownSuspense
fallback is always shownYou can inspect the code here : https://github.com/Fredkiss3/parallel-routes-modal-next/blob/main/src/app/pokedex/page.tsx link for vercel deployment : https://parallel-routes-modal-next.vercel.app/pokedex link for cloudfare deployment : https://next-on-cf.fredkiss.dev/pokedex link for railway deployment : https://parallel-routes-modal-next-production.up.railway.app/pokedex
i don’t have any idea as to why the fallback is not shown right away on vercel, i even tried to inspect the network tab on chrome to see if maybe the response from vercel wasn’t streaming, but i did not see anything unusual, the response seemed to be streaming normally and the network tab seems to be the same between vercel, cloudfare and railway.
Hello @arackaf thanks for reporting the issue, I attached a PR and fixed the issue. Tested here with your repro https://next-instant-loading-8nv6psqod-feedthejim.vercel.app , thanks a lot 😃
that totally makes sense, that’s why i’ve added throttling for testing on the client and delay on the api side. but isn’t it a job of page prefetch feature to get the loading state before navigating to it? and if that’s an intended behaviour, why does the first page loaded work differently (instant loading state on client every time)? and what is the reason to use streaming api with loading.ts feature in next.js if it is only useful (after 1s in your example) for API endpoints that take some significant time? for the most applications with simple db access endpoints its seems useless and client loading state would be preferred.
More than that Next.js docs say that loading.tsx should be instant compared to custom Suspense boundaries
I mean, I understand why it works the way you described for custom suspense boundaries, but it’s not obvious from the docs that the loading.tsx should work the same way
I’m still a fan of app directory, but honestly the “instant” loading feature feels misnamed, and I’m more or less convinced it shouldn’t be used at all if it’s not actually instant.
CDN request or not it cannot ever be considered “instant” if a network request is required in order to load and show it.
I’d love to just see these loading states be automatically included in all client bundles, with devs being responsible for understanding that bundles can grow if they build too many of them, with too much content.
It depends on your connection. Slow connections makes the whole app feel sluggish and not instant on route changes due to that extra roundtrip. Even on fast connections you’ll notice a delay. Its missing instant feedback something is loading.
I’m currently in the process of switching over to the App directory, coming from the pages directory. And altough I see the benefits the new App dir offers, this issue is what really makes me consider moving everything back. Because the overall UX just feels slower 😞
The slowness comes down to this extra fetch that needs to resolve before routing to a different page.
I don’t know enough about the NextJS and React internals of this. But it seems like the only logical fix is to have that in the client bundle in order for it to be instant.
edit: can you re-open this issue?
It looks like it’s hitting the server before showing the
loading.tsx
, this feels very sluggish, would’ve been better if theloading.tsx
is shown instantly upon user navigation. Tested on the latest canary 13.4.20-canary.27.https://github.com/vercel/next.js/assets/32889996/487b9973-74f0-4dfa-9211-0296e4182ae9
i am still facing this issue, my page is getting loaded after five clicks, using app router Link from ‘next/navigation’ pls do something, suggest me fix.
@rusted-love i also thought this was a bug, but this is expected, the solution is to use a different key to Suspense to force React to consider the Suspense as a different component each time and show the fallback, i’ve done something like that here : https://github.com/Fredkiss3/todo-app-beautiful-ux/blob/main/src/app/(routes)/(app)/%40todo_app/page.tsx#L49-L54
You could either encore the search params to string to set a unique key per search, or use
Math.random()
to have a random key each time and always show the fallback. Encoding the searchParams for the key could be interesting if the user refetch the same page, since the key is the same React won’t show the fallback and the user will still see the old content, while when navigating to another page, it will show them a fallback.I think this behavior is related to how
Suspense
work with transitions. the thing is that when usingSuspense
if the fallback have already been shown once, if you use a transition, React will hold the old data until the Suspense boundary has resolved, and Next uses transitions for all the navigations. Using a different key forces React to consider theSuspense
as a different component.This is from the React documentation here : https://react.dev/reference/react/Suspense#preventing-already-revealed-content-from-hiding
@timneutkens Was this released with the recent 13.5.4 version that dropped 3 days ago? I’m still seeing the same behavior.
Repo / branch are here https://github.com/arackaf/next-instant-loading/tree/feature/instant-loading
I want to clarify how loading UI works in Next.js.
Routing in the App Router is “server centric”. We need a network roundtrip to the server when doing route transitions. The client doesn’t know what loading state to render, until it communicates with the server.
When we prefetch, we can retrieve both the route to navigate to and the loading UI. Prefetching is what makes navigations feel snappy. If you prefetch the loading UI which does not have data fetching, then you can “instantly” show this loading state, followed by the dynamic content on the page being streamed in after. This is enabled through React Suspense and streaming server-rendering as part of the App Router.
We don’t believe an alternate solution where you include all of the routing variants on the client is feasible or the best solution for Next.js. For example, consider a loading state which is
100kb
of HTML / possible routes. Should that be included in the initial JavaScript bundle, blocking interactivity for everything on the page until it’s downloaded? Or, is it better to not block interactivity, and load it asynchronously before the next click? We still believe the current model is correct.There’s still opportunities for us to improve the experience of transitioning between loading states. For example, we can optimize further the de-duplication of data. Thanks for the reproductions here, as they’ll help us dig in further and find places to optimize.
Landed in https://github.com/vercel/next.js/pull/55950
The original reproduction is fixed when I tried with the new canary version with nextjs. The issue mentioned here about edge runtime streaming is fixed on vercel platform now.
Let me know if you still have any further problem, or if there’s new issue encountered, please file a new issue with reproduction. Thanks y’all for the information and investigation.
I created an issue for the
Suspense
case : #51033Two cents from our practical implementation side: we are noticing significant delays after clicking a button that performs
router.push()
. In the oldpages
setup, you would usually set up a global router listener to show a loading state, but there’s no recommended built-in way to do this with theapp
directory.From a UX perspective, you just clicked a button and nothing happens for a while until suddenly your page jumps to a new one 2-3s later. Definitely cache related, since this only happens on new deploys (to Vercel) and navigation is immediate on subsequent navigations.
It may be working as designed, but it doesn’t work. Relying on a lazy loaded response can and will lead to weird glitches with loaders. Separately, I would expect loading.js (and IMO suspense fallbacks) even in static/SSG sites to show the fallback if no RSC for the page or component has yet been downloaded, which can happen when prefetch prop is set to false.
It’s hard to not get the feeling that Vercel has planned for a heavy use of prefetching for their own concerns and we has devs should not just brush this under the rug and give them a pass. We are more or less forced by the industry to learn and use this tool, but it can be made better if you aren’t afraid to give them a little pressure about it. Prefetching all the things is a terrible idea. Worrying about adding 10-20k to a bundle is good, but never without consideration about the overall balance.
Nothing mentioned above helped. We expect
<Suspense>
fallback to be displayed each time page parameter changes. E.g./products?cat=shoes
and/products?cat=shoes&size=36
. As for now server component is waiting until api requests will be completed. In case of slow search customer does not see any effect caused by link click until request is fulfilled. This is weird. I hope this will be fixed as soon a s possible.@tonypizzicato , I’ve resolved same issue with group route. https://beta.nextjs.org/docs/routing/defining-routes#route-groups Look at my app route structure. Dynamic page uses the nearest parent loading.tsx, but announcements must has another loading.tsx. To resolve this problem, I used group route. I hope this solution works well for you.
@StampixSMO If you are manually call
router.push
you can wrap your call withuseTransition
, it will give you aisPending
state that you can use to show a loading state.An example usage :
But I would recommend using
Link
if possible to navigate between pages, as you don’t have prefetching enabled forrouter.push
.Absolutely agree with all problems raised in this issue, this is the only thing stopping our project from migrating to App Router - navigation creates just horrible experience with sometimes up to 300ms wait time before even the loading streams in (I know this can be solved by moving the server closer e.g. on edge, but that’s a different story). Other side of the problem is that there’s no way to display any other loading state on the UI while loading hasn’t streamed in yet - you are forced into this UX.
I truly don’t understand the reason behind this: if
loading.tsx
doesn’t accept any props and is essentially static (usually just a bunch of skeletons), why can’t we include it in client-side bundle (or at least opt-in to that)? Or event better - do not include it into a bundle, but fetch it and cache properly on the client - so that subsequent visits of the same page immediately show the fetch UI from client-side cache. That is probably how prefetch should work, but currently my experience is that it’s working in a very random fashion (even in NextJS playground: https://app-dir.vercel.app/streaming/edge/product/2)With
Suspense
it’s a bit different because it allows for granular control, but even then the initial state whereSuspense
is showing fallback could be used with the same approach.I checked @arackaf 's repo and environment. This shows the same issue i’m also seeing:
Demo: https://next-instant-loading.vercel.app/ Repo: https://github.com/arackaf/next-instant-loading/tree/feature/instant-loading
The issue also happens in production environments. The same RSC background fetch/prefetch call delays rendering of a loading indicator.
I see the prefetching happen for the pages that are linked to. But the same fetch happens when a user clicks the link to that page.
Now, nothing happens on the screen until that fetch resolves. Not even a loading indicator. Nothing. And this is exactly the point we try to make by throttling your connection. Not everyone has sub 50ms connections to the server at all times to get a server respond if we should even show a loading indicator…
I tried making a demo video of the issue. But it’s giving too much away of my environment, including url’s that I don’t want to be publicly available. But it’s the same issue as posted in the GIF a few days ago in this thread.
Also, this is worrysome yes. I already see a huge increase in calls that count up to my usage in Vercel, just by using the App Router.
It happens when you navigate, so clicking a link to a different page where that page is expected to show a loading indicator. So with a loading.tsx or a Suspense fallback. The above gif of @arackaf shows exactly what happens. He also has a reproduction repo.
To be more precise on where to look in that gif; its about the delay between the click and until the loading indicator is shown. Thát delay shouldn’t be there.
As an alternative, if Vercel absolutely, does not want to include all loading components in client bundles, can I suggest Vercel add an ability to do something like
to a loading file to force it to be included in client bundles, to enable them to be actually instant?
Will there be any response from the Vercel team? Should we wait for a fix, or can we start migrating to another hosting provider?
yeah Vercel also didn’t allow me to send stream from a route.tsx file as a response it worked locally but on Vercel it didn’t work so we deployed our app on cloud run and it worked there. thanks for your example it really helped a lot
I challenged the same problem. Thanks to useTransition I was able to add a loader before redirect to requested page. As you can see on the attached video with simulated fast 3G connection - when loading.tsx is being fetched it shows a loader instead of the link, then it shows loader from loading.tsx until it’s fully loaded.
https://github.com/vercel/next.js/assets/8022830/d9044b48-ce74-4e4e-9d00-9db123ee0b4f
Hey I have the same issue, is there maybe any way to work around (so the moment I click on the link, some kind of loading state is shown). I wrote (almost) everything with server side components, so my app works properly without (almost) any JavaScript enabled in the browser. Is there any (maybe even dirty) workaround, so I do not have to migrate back to pages directory?
Just wondering if there is anyone that disagrees that the “ideal” behavior for a suspense boundary (either loading.js or manual) would be to show a fallback whenever its children aren’t available, regardless of the reason being work is being done on the server, network delay, etc. If you have a reasoning this wouldn’t be the “ideal” (technical issues aside), it would be interesting to hear.
In my mind anything short of fallbacks firing as soon as the parent DOM is available (during initial load or client transition) up until the at least the time the children begin to render on the screen is a bug. Sometimes a serious show stopping bug depending on the case. Updates based on search filters, etc. should probably be the same, although I feel at least in this case you have options to manually control the behavior if you like.
@Fredkiss3 the issue with suspense. It already discussed before by other participants. We decided to revert our app to the client side rendering for all routes.
After several attempts, I realized that the issue for me was using
generateStaticParams
. I’m not sure why, but removing it solved the problem.Hey, not sure what made you offended… it certainly wasn’t my intention. I’m not even really frustrated. Just evaluating Next.js and server components on a simple app and made some observations. If you don’t like them, that’s ok, we can disagree. That said, my opinions were only about Next.js and the decisions they’ve made, not you in case you felt that for some reason. Vercel is a for profit company and I respect that Next.js (and you and I) are a business model for them. I have no issues with that. But I also don’t see a problem with discussing the potential pitfalls of that situation. And there are some. Just on the Link/prefetching issue for example there are numerous threads (Google and you’ll find) going back several years of people not happy with the inability to turn off without creating your own <Link/>. If they fixed it recently, good on them.
Anyoo, I’ve 100% come in peace with the goal of discussing my experience with this issue.
There is a PR about a potential solution for this : https://github.com/vercel/next.js/pull/49077
TLDR : next will now prefetch pages content until it finds a
loading.tsx
which will be prefetched also.Edit :
Tested it on the latest canary and it works : https://github.com/Fredkiss3/next-13-loading-prefetched . Before, next did not do any real prefetching (it did not run the page on the server), now next will prefetch the page until it finds a
loading.tsx
file, so that on navigation the loading fallback will show instantly, it works also with suspense.For suspense there is something interesting : if the page is prefetched (either on hover on DEV, and by default on production), it will eagerly run and return the suspense boundary, and if suspense resolves before you navigates to that page, you won’t see the fallback but the page directly. this one is pretty cool.
Updated this example which is more complete : https://github.com/Fredkiss3/parallel-routes-modal-next
I think it comes down to justifying behaviors because of what may seem to make sense “technically”. But with user experience, you do your best to achieve behavior based on what the user would expect and prefer. If the cost is high, you sometimes have to compromise of course. I’m not going to have one of the first tickets to Mars for example. My UX is probably going to be going camping instead. But since I don’t think this is quite rocket science and Sever Components are still new, it seems like a good time to focus on what the UX of it should be.
I think the acceptance of this is a Next thing… coming from the fact that getServersideProps was accepted as the norm even though it was always bad UX. There were always better ways to handle client route changes via lazy loading such as this, which allowed finer control of the experience that what GSSP offered. RSCs are an upgrade over both methods, but the fallback situation is still less than ideal. It may work fine in some situations, but in others it doesn’t. There’s no reason why React and Next can’t fix it if they want. Just show the fallback as soon as the route transition begins and stop showing it when the rsc is ready to hydrate. I’m not an expert on Server Components, haven’t watched any two hour videos and don’t currently have time, but I just can’t image what the technical barrier to that could be.
For link navigations manual
<Suspense>
, do not show until after a network request, instead the the current page is shown (because ofuseTransition
), this is because react cannot know if one of your components will suspend or not, so it makes a request to the server and as soon as it finds a suspense boundary it automatically flush out a response with the fallback, then a little while after, it shows the complete page, you might have a request that only suspend on the first render (like the page i just shared, which suspends only on first request and uses client side fetching when navigating to make it fast for navigations).For
loading.tsx
however it seems to work a little differently. Here is what i understand :loading.tsx
for a route in the first navigation, then for the subsequent navigations it reuses theloading.tsx
file if it is for the same segment.loading.tsx
directly.I have an exemple without prefetching which shows the loading spinner only after a delay then show them instantly on subsequent navigations
I also have an with prefetch=true that shows them instantly
I think the logic of the react team is that Suspense gives you the power to show the loading spinner whenever you like, by default it does not do exactly that, but you can take over this by using a transition, i’ve done something like that here : https://parallel-routes-modal-next.vercel.app/boards_search/oWNLDSH2nQTVrDcWS3zg7o
You can see here that the suspense boundary show up instantly because i suscribed to the
isPending
given by useTransition.However this example is very hacky as i have to opt out of the link component entirely : https://github.com/Fredkiss3/parallel-routes-modal-next/blob/c9443997ebc8ccaadc03c0a68a2e8ab17ed1f260/src/app/boards_search/[bid]/card-list.tsx#L41
I think the canonical solution here is the loading.tsx file, you just have to make sure to place them in the right place and add prefetching.
Yeah, that’s exactly what I suspect the intention is but I don’t think it’s good UX. A better version of the Fallback would start running on client as soon as the dom is available, and/or as soon as a route transition begins if inside a layout. Then ending either as soon as content starts to paint, or when its finished (probably best). We can disagree on this, but there’s no reason why it can’t be implemented this way… and no reason I can think of that it wouldn’t be a better user experience than a loader that appears before and/or after a pause. It already works like that in loading.tsx for the most part (seemingly with bugs), which is why you see the transition between pages on site that’s static.
I get that it appears to work more nicely in situations where the server component has more work do (nice work on your site). But in other situations where the reason for the delay is network, browser parsing, etc, especially a page that already has content… it shouldn’t matter what is causing the delay when it comes to fallback behavior. With client components we can use useEffect and have that control. But right now with server components you only have the behavior the Suspense fallbackoffers.
Interesting what you originally pointed out about the prefetched text files on my site. Just noticed it. I think they’re just the static RSC output which for some reason on a static exported site have a txt extension (normally I think they’re rsc). But I could be wrong!
I guess my issue lies in the use of
<Suspense>
on a page to have fine grained control over what component is loading, instead of a page wide loading indicator.Using Vercel’s app router demo to demonstrate:
No issue here when using a generic loading.tsx file: https://app-router.vercel.app/loading
But the issue is here “Streaming with Suspense”: https://app-router.vercel.app/streaming
When you throttle the connection, using loading.tsx instantly shows a indicator. Which is good. But using the same throttled connection on the Streaming With Suspense demo prevents anything from being shown until a certain point. Not really clear when that exactly is.
Both also tested with the latest NextJS version locally and with a deploy on Vercel.
So the issue lies in the use of
<Suspense>
with a fallback on a page.tsx. When I switch over to using the loading.tsx the issue dissapears in my project. But that’s not what I hoped, I really want to use the Suspense fallback on a per component basis and not have a loading.tsx on the page level.edit: issue about this: https://github.com/vercel/next.js/issues/54667
Thanks for clearing that up @IGassmann ! I’ll have to take another look at my code then. Because i’m on the same latest Next version but dó see the delay. I’m just totally lost now what’s causing it.
Hey all - sorry, yeah the original prod repro may not be on the latest commit. I’ll take a look later and update.
I’m glad to hear it’s instant with a prefetch, but I would still feel much much much better if it was just included in the JS bundles for a number of reasons articulated above by others.
Instant loading state should not depend on a prefetch.
@feedthejim, this is a challenging request. Users may encounter poor internet connections, such as when using the app in the subway. For example, a user might load a page right before entering a tunnel and then, while in the tunnel, click a navigation link, which could result in no loading indicator. How do you provide a reproduction for this situation?
@unleashit I’m asking for a real repro where I don’t have to simulate 3G conditions to notice a delay
@IGassmann we disable prefetching in dev because it would force the compilation of all the pages that you’re linking to from your page. Please do note that if you do click a link in dev, we simulate the prefetching behaviour however by fetching the loading state first and then the rest.
Yes and
Both of these are the bottom line, and what I (and some others) tried to argue months ago.
This would be the opt-out method, which be a big improvement since it would fix more than this issue and give the dev a choice on how they want to balance performance (faster initial load vs faster transitions without relying on prefetch). Personally I prefer the (traditional) opt-in approach to code splitting, which is really as simple as a dynamic import per component (or page) you want to code split/lazy load.
Suspense doesn’t trigger again when
key
matches the second time, so if you push searchParams into the url you’ll want to add akey
that changes. For example:That’s a fair solution to the delay. But then to keep the good user experience of instant feedback, you need two “loading” implementations every time, which is a pain when coming from a SPA mindset.
So my current component inside app/page.tsx looks like this:
And I have a
loading.tsx
at the same level. But when I click on this Link (if I have not clicked on it before). There is nothing happening for 1s, then the loading state of theloading.tsx
is displayed. I tried it out on the latest next stable release and on canary. It is the same on both versions. I can try to convert all of the things usingLink
to client side and try the workaround withuseTransition
mentioned above.Edit: I tried it out with
useTransition
and the pending state works. I will rewrite my navigation components like this for now. But I think it is definitely a good proposition to useloading.tsx
at the same moment as the pending state ofuseTransition
is set to true. As this is the only thing holding me back right now from doing everything server sided (server actions work very well for me btw 🥳 ).@DoctorManhattan123 if you have a loading state, then it is working normally… right ? What is the issue ?
You have to note : if you are on the latest version (
next@13.4.4
), there have been a rework of the way prefetching works, so by default if you have a link pointing to the destination path, you will see the loading state as soon as possible if the page have been prefetched (it is activated if theLink
is in the viewport).@Fredkiss3 Thank you for information. It helped me a lot. In our case main issue was caused by slow
generateMetadata
. I thought thatgenerateMetadata
result is lazy-injected in order to improve TTFB metric. Hope with timegenerateMetadata
will be lazy-injected for non-robot users.I don’t see why it isn’t fixable. For each suspense, add a HOC to the client bundle that loads the fallback immediately on mount. Then end it once it has children. Seems like loader.js is already doing that (although not perfectly), and probably not far off from a normal suspense. I would think this is probably something for Next rather than React to do. Of course I’m being an arm chair directory who hasn’t taken the time to look at the code, but if this issue is for some reason unsolvable than in my opinion is is a big mark against server components.
I appreciate the ideas! For my little project I won’t sweat it too much. I’ve looked at useTransition and it seems more for not blocking the UI when doing some work? I’ll have to check that out at some point.
@unleashit Normally the
Suspense
boundary is supposed to always show if your page is SSR’ed on a full page refresh, that’s because of streaming (something like this : https://locaci.fredkiss.dev/search). If it don’t show with SSR, then it might be a bug, it might also be because your data fetching is very fast, what throttling does is only slow down you request to the server, if it is fast enough you will sometimes get a flash of loading states, or maybe not at all since when the browser receives the response your suspense boundary has already finished loading.You could try to add an artificial delay to your fetches of for ex 1 to 2 seconds, to see it better.
It seems that to make loading instant you have to define it on the parent folder of the dynamic route like they do in App dir playground repository.
You can also use route groups like in @devdreamsolution comment : https://github.com/vercel/next.js/issues/43548#issuecomment-1497829622