Resource loading from param blocks navigation
https://stackblitz.com/edit/github-xdufjx?file=src%2Froutes%2Fdetail%2F%5Bid%5D%2Findex.tsx
on latest solidstart
When navigating to
/details/a
from /
, suspense fallback shows. After data loads, now navigate to detail b and see how the page freezes. You can't go to home during this.
Shouldn't the suspense show and not block everything when going a -> b? Not sure if i'm doing something wrong here.10 Replies
1. Don't use
createResource
with cache
. That's what createAsync
is for.
2. cache
implicitly triggers a transition. Consequently rendering happens offscreen and the page isn't swapped in until all async sources have settled. Compare to:
https://www.solidjs.com/tutorial/async_transitions?solved
Using smart cache opts into the route loading the data (rather than through components) so for a nested route update the screen doesn't change until the route render is ready. The rendering of fallback child content while any async sources have not yet settled is more aligned with the philosophy of component data loading.
3. Now the odd bit: plain createResource
(bypassing cache
) should let you opt out of implicit transitions and load component data after routing.
https://playground.solidjs.com/anonymous/dcf477cc-c879-4c8d-81f0-21bc377633eb
However right now in the context of SolidStart createResource
also triggers transitions and I don't know why.
https://stackblitz.com/edit/github-xdufjx-hxnbnc?file=src%2Froutes%2Fdetail%2F[id].tsxSolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
StackBlitz
Solid-start With Tailwindcss Example (forked) - StackBlitz
Run official live example code for Solid-start With Tailwindcss, created by Solidjs on StackBlitz
Thanks for this. Yeah basically I want to opt out of the transitions because if the page has multiple resources, I don't want 1 slow resource to pause the navigation.
Would you say this is a bug that
createResource
does this?
https://stackblitz.com/edit/github-xdufjx-uf411k?file=src%2FAPI.tsWould you say this is a bug that createResource
does this?
I can't be sure.
AFAIK createResource
is slated to be replaced by createAsync
by SolidJS 2.0 and I was under the impression that implicit transitions are supposed to be part of solid-router but if createResource
is now already being integrated in this fashion then I'm missing what the transition escape hatch would be.
There has been an open issue since January
https://github.com/solidjs/solid-router/issues/352
but it pertains to createAsync
—as there is no response, I'm assuming it's being treated as a documentation issue about opting into implicit transitions; solid-router is trying to emulate browser routing behaviour and avoid screen tearing.
https://twitter.com/jaffathecake/status/1529370639915687936
I also observed some things that made me wonder whether I was starting to see things.
Transitions exist to enable alternate branch rendering while paint holding but
props.params.id
inside createResource
updates immediately on navigation but inside of createEffect
(and by extension render effect) it only updates once the transition has completed - so it almost looks like transitions also delay change propagation on effect boundaries (i.e. not only paint-holding but also value-holding).
At this point I feel like I have to look at a fresh project to see whether this behaviour is consistent.GitHub
not properly triggering nested Suspense · Issue #352 · solidjs/sol...
Describe the bug When using A components for navigation to pages which rely on params or location to render, it is not properly triggering nested Suspense fallbacks. It instead waits until the enti...
Jake Archibald (@jaffathecake) on X
@BigupJeff In normal browser navigations, the URL only changes when the old content becomes inert. That only happens when it has a response for the new content.
Try it with some network throttling 😀
Twitter
So it may be a bug—another explanation is that solid-router is moving away from using fallbacks available in core but will instead force you to pro-actively set up an “optimistic view” before entering a transition.
That workaround in the issue does seem like a viable escape hatch that makes sense since you exclude the resource from the navigation transition. Although it might not be obvious to figure out. Might just need some more documentation around it.
I believe
createAsync
is just a higher-level wrapper around createResource
so the transitions work the same.
I experience the same behavior you describe for the effect param value holding. To me this seems intentional? Since you want to hold the same state during the transition.Since you want to hold the same state during the transition.In principle I agree but effectively it defeats any workarounds. What seems to be happening is that the alternate rendering branch is limited to the DOM subtree under the closest suspense boundary while the value-holding applies to the entire page—which makes sense if you are trying to emulate browser behaviour, keeping the stale page stable until the new page is ready to render. That said, value-holding will lead to screen tearing for anyone trying to get fallback+optimistic values to work. Based on your example I tried this: This will render the fallback once the transition starts but the
<h1>
will display the stale value (which is consistent with the URL in the address bar which doesn't change until the transition ends).
So from the user perspective there is an indication that something is happening but there is no obvious way to provide the optimistic value to the <h1>
which is what the typical developer intent would be.
FYI: I found useTransition
to be more reliable/useful than useIsRouting
in this example.
So the broader message seems to be: stop relying on component level fallbacks.
Given that the page doesn't have access to the browser's reload button appearance, it needs to include exactly one element to indicate background/busy activity which at the very least triggers when a transition is pending.Interestingly the React RSC demo used a spinner inside the search field which in my port I drove with
https://github.com/peerreynders/solid-start-notes-basic/blob/ea9ed12a4b642e5295537f49b2613d460c21e6be/src/components/search-field.tsx#L47 Compare that to the solid-start example: https://github.com/solidjs/solid-start/blob/2d75d5fedfd11f739b03ca34decf23865868ac09/examples/notes/src/components/SearchField.tsx#L30 Bingo—it uses
useIsRouting
https://github.com/peerreynders/solid-start-notes-basic/blob/ea9ed12a4b642e5295537f49b2613d460c21e6be/src/components/search-field.tsx#L47 Compare that to the solid-start example: https://github.com/solidjs/solid-start/blob/2d75d5fedfd11f739b03ca34decf23865868ac09/examples/notes/src/components/SearchField.tsx#L30 Bingo—it uses
useTransition
.
I take this as evidence that the current createResource
behaviour is working as intended.
It's trying to wean you off component level fallbacks and drive you towards one single page level busy indicator.GitHub
solid-start-notes-basic/src/components/search-field.tsx at ea9ed12a...
Basic client rendered notes app using SolidStart beta - peerreynders/solid-start-notes-basic
GitHub
solid-start/examples/notes/src/components/SearchField.tsx at 2d75d5...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
I landed on a similar solution by dimming the page and a loader in the navbar in my app to indicate this to the user.
I guess
useTransition
would be more correct
I still think having component level fallbacks make sense in some cases like the one I show, with multiple resources where 1 is slow, relying only on a page level indicater seems like bad ux.
Similar to how you can add deferStream
to indicate which resources need to load before flushing the page.relying only on a page level indicater seems like bad ux.See Nielsen Norman Group: Skeleton Screens 101 and anecdotally: https://twitter.com/malchata/status/1456649407760408576 To answer your original question solid-router is deliberately guiding you towards this approach: https://stackblitz.com/edit/github-xdufjx-hxnbnc?file=src%2Fcomponents%2Fglobal-loader.tsx,src%2Froutes%2Fdetail%2F[id].tsx
malchata.htm (@malchata) on X
what is it with financial institution websites and the cavalcade of like fifteen loading spinners
Twitter
StackBlitz
Using a global loader for transitions - StackBlitz
solid-router's implicit transitions discourage page partial loading fallbacks in favour of paint-holding the stale page while showing one central loading indicator.
Nielsen Norman Group
Skeleton Screens 101
A skeleton screen is used as a placeholder while users wait for a page to load. This progress indicator is used for full page loads and reduces the perception of a long loading time by providing clues for how the page will ultimately look.
Yeah I see where you are coming from, totally agree that many sites have gone too far with loaders. But take youtube for example, navigating to a new video has similar transition hold for the main data with a page loader, but it no longer holds waiting for comments to load. I think waiting for secondary data to load before showing a page is worse.