Is My Data Being Fetched Server Side or Client Side?
Answered
Philippine Crocodile posted this in #help-forum
Philippine CrocodileOP
Really a noob question, but I'm going through the tutorial (https://nextjs.org/learn), and I have just implemented up to chapter 10.
I've done the streaming bit and the skeleton bits to allow for cases where it takes long to retrieve data from the DB.
However, it seems that the data at this point is being pre-rendered, since the components are all Server Components, rather than Client Components.
Surely, then, since this is all being pre-fetched by the server, rendered on the server, the skeleton and streaming bits are unneeded?
Were they just added in for didactic purposes?
I assume then that the dev server (npm run dev) does not do any form of pre-rendering, as it would happen on a production server?
I've done the streaming bit and the skeleton bits to allow for cases where it takes long to retrieve data from the DB.
However, it seems that the data at this point is being pre-rendered, since the components are all Server Components, rather than Client Components.
Surely, then, since this is all being pre-fetched by the server, rendered on the server, the skeleton and streaming bits are unneeded?
Were they just added in for didactic purposes?
I assume then that the dev server (npm run dev) does not do any form of pre-rendering, as it would happen on a production server?
Answered by LuisLl
No no, statically generated means Next.js can go ahead and render your page on build time because that page does not depend on any request-time data, dynamic APIs (params, searchParams, cookies, headers), or the data it needs will not change at all. So in these cases it makes sense to only ever generate the page once at built time and re-use that page every time a user requests it.
In the other hand…
Server components are just Components that happen to be entirely rendered on the Server, only their output is sent to the Client. They output is what’s called a React Server Component payload, which is basically a format that contains a description of the UI they will display. (If you’re familiar with the React Virtual DOM, imagine RSC payloads as Little chunks of Virtual DOM). Since Server components are already on the Server, Next.js can do more and also go ahead and use that RSC payload to Generate static HTML.
In the other hand…
Server components are just Components that happen to be entirely rendered on the Server, only their output is sent to the Client. They output is what’s called a React Server Component payload, which is basically a format that contains a description of the UI they will display. (If you’re familiar with the React Virtual DOM, imagine RSC payloads as Little chunks of Virtual DOM). Since Server components are already on the Server, Next.js can do more and also go ahead and use that RSC payload to Generate static HTML.
16 Replies
<Suspense> boundaries and loading.tsx (which are also a Suspende boundary wrapping your page) are meant to wrap dynamic parts in order to let the rest of your app pre-render.
When your React tree is pre-rendering on the server it’ll send the Suspense fallback (skeleton) in the initial HTML for the segments that are dynamic and inside <Suspense>, that way it can pre-render as much as possible, allowing the dynamic parts to stream in when they’re ready
When your React tree is pre-rendering on the server it’ll send the Suspense fallback (skeleton) in the initial HTML for the segments that are dynamic and inside <Suspense>, that way it can pre-render as much as possible, allowing the dynamic parts to stream in when they’re ready
If you’re seeing skeletons in your app it means React suspended the rendering of your component and instead sent the fallback
Philippine CrocodileOP
So... let's say I navigate to cool-website.com/something
Where "something" retrieves data from a DB. If I don't specify "use client", it is by default a server component, right?
So, does that mean that:
1. user makes request to cool-website.com/something
2. the nextjs server that is hosting "cool-website.com" makes a db request to get data
3. the nextjs server populates the cool-website.com/something page with said data
4. the nextjs server sends the cool-website.com/something page back to the client, populated with the data?
Where "something" retrieves data from a DB. If I don't specify "use client", it is by default a server component, right?
So, does that mean that:
1. user makes request to cool-website.com/something
2. the nextjs server that is hosting "cool-website.com" makes a db request to get data
3. the nextjs server populates the cool-website.com/something page with said data
4. the nextjs server sends the cool-website.com/something page back to the client, populated with the data?
If your server component is async and awaits its own data in the body of the component yes, it’s guaranteed that by the time your component shows on the client it already fetched the data on the server
If this database call is supposed to run on every request with new data then your whole page will be marked as dynamic and it’ll be requested when you navigate to it, to avoid bad user experiences or blocked navigations then you can provide a loading.tsx. For pages that you want or need to only be generated once at built time and re-use the cached page every time make sure to mark the page with export const dynamic = “force-static”
Philippine CrocodileOP
OK, so a server component isn't built once at build time. Rather, the request to the DB just happens at the server, per user request?
I don't quite get the code in the image I've attached, then.
RevenueChart is an async component, that awaits data from DB.
What's the point in a suspense boundary, if the returned component will just be sent back with data
RevenueChart is an async component, that awaits data from DB.
What's the point in a suspense boundary, if the returned component will just be sent back with data
@Philippine Crocodile I don't quite get the code in the image I've attached, then.
RevenueChart is an async component, that awaits data from DB.
What's the point in a suspense boundary, if the returned component will just be sent back with data
In this case this page be statically generated and the generated content will include the fallbacks (skeletons) of your Suspense boundaries.
The Suspense is needed to tell React the content under Suspense will take time and will suspend, and while that process is kicking off in the background React will display the fallbacks immediately.
Suspense will mark the parts of your component tree that are dynamic so they don’t need to be waited for in order to return a Response to the client. Makes sense?
The Suspense is needed to tell React the content under Suspense will take time and will suspend, and while that process is kicking off in the background React will display the fallbacks immediately.
Suspense will mark the parts of your component tree that are dynamic so they don’t need to be waited for in order to return a Response to the client. Makes sense?
There’s nothing that indicates that that page has to be generated on demand (when you request a navigation)
Next.js will try to keep as much of your app static if possible
@LuisLl In this case this page be statically generated and the generated content will include the fallbacks (skeletons) of your Suspense boundaries.
The Suspense is needed to tell React the content under Suspense will take time and will suspend, and while that process is kicking off in the background React will display the fallbacks immediately.
Suspense will mark the parts of your component tree that are dynamic so they don’t need to be waited for in order to return a Response to the client. Makes sense?
Philippine CrocodileOP
Hmmm... when you say statically generated, does that mean "Server Component"?
No no, statically generated means Next.js can go ahead and render your page on build time because that page does not depend on any request-time data, dynamic APIs (params, searchParams, cookies, headers), or the data it needs will not change at all. So in these cases it makes sense to only ever generate the page once at built time and re-use that page every time a user requests it.
In the other hand…
Server components are just Components that happen to be entirely rendered on the Server, only their output is sent to the Client. They output is what’s called a React Server Component payload, which is basically a format that contains a description of the UI they will display. (If you’re familiar with the React Virtual DOM, imagine RSC payloads as Little chunks of Virtual DOM). Since Server components are already on the Server, Next.js can do more and also go ahead and use that RSC payload to Generate static HTML.
In the other hand…
Server components are just Components that happen to be entirely rendered on the Server, only their output is sent to the Client. They output is what’s called a React Server Component payload, which is basically a format that contains a description of the UI they will display. (If you’re familiar with the React Virtual DOM, imagine RSC payloads as Little chunks of Virtual DOM). Since Server components are already on the Server, Next.js can do more and also go ahead and use that RSC payload to Generate static HTML.
Answer
Philippine CrocodileOP
Aha! Thank you!
I think I was mixing up the concepts... I assumed that having <Suspense> boundaries meant that the content within the <Suspense> boundary had to be a Client Component.
But in actuality, you can have an app entirely using Server Components and still make use of <Suspense> boundaries, since the content within that <Suspense> boundary will take longer to "get", let's say, because it's doing some heavier computation...
I think I was mixing up the concepts... I assumed that having <Suspense> boundaries meant that the content within the <Suspense> boundary had to be a Client Component.
But in actuality, you can have an app entirely using Server Components and still make use of <Suspense> boundaries, since the content within that <Suspense> boundary will take longer to "get", let's say, because it's doing some heavier computation...
Exactly, Suspense is agnostic to the environment, either React runs on the Client or in the Server. Glad you got it now!;)
About what you said:
It’s not necessary a heavier computation, it’s an async computation, an async task that’s not ready at the time React is rendering your components.
About what you said:
The content within that <Suspense> boundary will take longer to “get”, let’s say, because it’s doing some heavier computation.
It’s not necessary a heavier computation, it’s an async computation, an async task that’s not ready at the time React is rendering your components.
<Suspense> boundaries get trigger when a promise is encountered during Render and you try to access its value and it’s not ready yet.
What happens is that React throws (these are implementation details anyway) and terminates the execution of that component, displaying the fallback instead (suspending it), until the promise is resolved and React can re-render the component now with the data.
What happens is that React throws (these are implementation details anyway) and terminates the execution of that component, displaying the fallback instead (suspending it), until the promise is resolved and React can re-render the component now with the data.
Philippine CrocodileOP
Thank you!