Consider this Next.js server component using streaming:
export default async function Page() {
const data = await fetch('https://api.example.com/data').then(res => res.json())
return (
<main>
<h1>Welcome</h1>
<section>{data.message}</section>
</main>
)
}What part of the page will the browser display first during streaming?
export default async function Page() { const data = await fetch('https://api.example.com/data').then(res => res.json()) return ( <main> <h1>Welcome</h1> <section>{data.message}</section> </main> ) }
Without Suspense boundaries, top-level awaits in server components block rendering of the entire page.
Awaiting the fetch before returning JSX means the server waits for all data before rendering and streaming any HTML. No partial streaming occurs.
Choose the correct way to use React Suspense for streaming in a Next.js server component:
import React, { Suspense } from 'react'; function Loading() { return <p>Loading...</p>; } async function DataComponent() { const data = await fetch('https://api.example.com/data').then(res => res.json()); return <p>{data.message}</p>; } export default function Page() { return ( <main> <h1>Title</h1> {/* Suspense usage here */} </main> ); }
Remember Suspense expects components, not promises or awaited JSX.
Suspense wraps components that may suspend rendering. Async components must be used as JSX elements without awaiting inside Suspense.
Given this Next.js server component using streaming, why does the browser wait for all data before showing anything?
export default async function Page() {
const user = await fetch('/api/user').then(r => r.json())
const posts = await fetch('/api/posts').then(r => r.json())
return (
<main>
<h1>Hello {user.name}</h1>
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
</main>
)
}export default async function Page() { const user = await fetch('/api/user').then(r => r.json()) const posts = await fetch('/api/posts').then(r => r.json()) return ( <main> <h1>Hello {user.name}</h1> <ul> {posts.map(post => <li key={post.id}>{post.title}</li>)} </ul> </main> ) }
Think about when the component returns JSX in relation to async calls.
Awaiting both fetches before returning JSX means the server waits for all data before sending any HTML, blocking streaming.
Analyze this Next.js component using nested Suspense for streaming partials:
import React, { Suspense } from 'react';
function LoadingUser() { return <p>Loading user...</p> }
function LoadingPosts() { return <p>Loading posts...</p> }
async function User() {
const user = await fetch('/api/user').then(r => r.json())
return <h2>User: {user.name}</h2>
}
async function Posts() {
const posts = await fetch('/api/posts').then(r => r.json())
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
}
export default function Page() {
return (
<main>
<h1>Dashboard</h1>
<Suspense fallback=<LoadingUser />>
<User />
</Suspense>
<Suspense fallback=<LoadingPosts />>
<Posts />
</Suspense>
</main>
)
}What will the user see first in the browser?
import React, { Suspense } from 'react'; function LoadingUser() { return <p>Loading user...</p> } function LoadingPosts() { return <p>Loading posts...</p> } async function User() { const user = await fetch('/api/user').then(r => r.json()) return <h2>User: {user.name}</h2> } async function Posts() { const posts = await fetch('/api/posts').then(r => r.json()) return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul> } export default function Page() { return ( <main> <h1>Dashboard</h1> <Suspense fallback={<LoadingUser />}> <User /> </Suspense> <Suspense fallback={<LoadingPosts />}> <Posts /> </Suspense> </main> ) }
Suspense fallback shows while async components load.
The <h1>Dashboard</h1> renders immediately. Suspense shows fallback placeholders for User and Posts until their data loads, then replaces them with real content.
Choose the best explanation for why streaming and partial rendering with React Server Components improves performance in large Next.js applications.
Think about how streaming affects perceived loading speed and interactivity.
Streaming sends HTML in parts as soon as they are ready, so users see content faster. This reduces waiting and improves perceived performance, especially for large apps.