Skip to content

Comments

Tweak Next 13 demo loading#268

Merged
alunyov merged 6 commits intorelayjs:mainfrom
alvarlagerlof:tweak-next-relay-loading
Jan 17, 2023
Merged

Tweak Next 13 demo loading#268
alunyov merged 6 commits intorelayjs:mainfrom
alvarlagerlof:tweak-next-relay-loading

Conversation

@alvarlagerlof
Copy link
Contributor

@alvarlagerlof alvarlagerlof commented Jan 8, 2023

I experimented with trying to make the demo work for my usecase. I needed to be able to server render full content while still being able to use Relay features after initial server load.

Much of the work had already been done (thank you @alunyov), so it only took a few twaks in the end to get it working (but some time).

I have a few observations and questions:

  • It looks to be doable without modifications to Relay itself.
  • Using usePreloadQuery in <Suspense>seems to always cause hydration errors. Probably returns something other than the data on the first render. Although this is only true client-side.
  • Should usePreloadQuery be wrapped with <Suspense> in the first place?
  • Is there a reason not to define <RelayEnvironmentProvider>in layout.tsx?

Other than that I think looking at the commit messages in this PR will explain the changes I've made.

Some are just to demonstrate that thet changes are working, and I expect to remove them before this PR is considered for merging.

That way the provider is defined once for the whole app instead of per page.
It seems that using `usePreloadedQuery` inside a `<Suspense>` on a client component will cause it to always suspend on the client, which it doesn't need to. If it does, an hydration error occurs.

Moving to after `usePreloadedQuery`, to the data or fragments that it renders works fine however.

We still need it to be able to render a fallback in case a fragment is refetched.
Since moving the `<Suspense>` boundary down one level in the tree, we no longer get any loading status. Creating a `loading.tsx` wil let us achieve the same effect as before.

This could also be an explicit Suspense boundary around `loadSerializableQuery`.

Removing or renaming `loading.tsx` will let you see the full server-rendered content as a search engine would see it once Next.js releases "Skip streaming for web crawlers" on their [roadmap](https://beta.nextjs.org/docs/app-directory-roadmap).
This button is just here to prove showcase that relay has `<Suspense>` to be able refetch data clientside while still rendering a fallback correctly.

I expect to remove this commit later.
Added some extra description text to show if a loading status is from a server component or in the client.

I expect to remove this commit later.
@alvarlagerlof
Copy link
Contributor Author

alvarlagerlof commented Jan 8, 2023

I am thinking: While this does work, and is server rendered, there is only server components on the top layer. In some ways this is already good considering you do get the code maintainability of Relay fragments. Also lacking many of the potential network transfer improvements of RSC.

I think I'd want to be able to specify fragments in server components even further down, possibly only going to server components at the edges of things.

If I imagine a shopping site and the "add to cart button" is the only one that is a server component for example. Then maybe only that one could be updatable (without reloading the whole page). That would lean more heavily into RSC, but I don't know if that is possible right now. One problem is probably how to pass just the cart button data to the store, since all of its parents are in server components. Maybe something is possible with createServerContext?

But then again I don't know if that is something you'd want. Relay does give the ability to fetch a lot of a page at once, which is one thing that server components lets you split up.

I could also think that somehow combining RSC with @stream might be very interesting, and not something you could do with "use client" (while keeping the SEO/server rendered benefits).

Since moving the loading status to loading.tsx from the client suspense, the loading text is no longer positioned like the main content. Moving the styles to the layout resolves this.
@davidmccabe
Copy link
Contributor

Alvar, thank you so much for jumping in and putting this together! It's incredible to see you go from 'interested' in your first tweet to moving things forward in a PR a day or two later.

Still catching up on understanding this thread, stay tuned

@alunyov
Copy link
Contributor

alunyov commented Jan 11, 2023

@alvarlagerlof thanks for looking into this. I also spent some time thinking about how we can evolve this integration: #269 - please let me know what do you think.

Copy link
Contributor

@alunyov alunyov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alvarlagerlof for this contribution!

@alunyov alunyov merged commit 664ac8b into relayjs:main Jan 17, 2023
@alvarlagerlof
Copy link
Contributor Author

Might want to remove the refetch button.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants