Explain streaming with Server Components, Suspense, and loading.js
Tests progressive HTML streaming through Suspense boundaries. Strong answers state loading.js auto-wraps a route segment in Suspense so the server can stream the shell instantly and defer slow data without blocking first paint.
WHAT THIS TESTS: This question probes whether you understand the difference between traditional SSR all-or-nothing rendering and React's streaming model in the Next.js App Router. The interviewer wants to see that you know Server Components can suspend on async IO, that the server can emit HTML in chunks, and that loading.js is a framework convention rather than a client-side state management pattern. They are also checking if you can connect architecture to user experience metrics like TTFB and LCP.
A GOOD ANSWER COVERS: First, define streaming as the progressive transmission of HTML from the server to the browser. The shell renders immediately while slow data fetches are pending. Second, explain that loading.js is a special file in the App Router that Next.js automatically wraps around the route segment as a Suspense fallback. Third, describe the lifecycle: the server sends the static shell plus the loading UI first, then when the suspended Server Component resolves its data, Next.js streams a small inline script and the final HTML chunk to replace the fallback. Fourth, tie this to UX by noting that TTFB stays fast because the browser does not wait for the slow query, and LCP improves because meaningful pixels paint earlier. Fifth, mention that because the work stays on the server, the client bundle does not bloat with data fetching logic.
COMMON WRONG ANSWERS: A major red flag is describing loading.js as a client-side spinner driven by useState or useEffect. Another is saying you must manually wrap every page in a Suspense boundary; loading.js exists precisely to avoid that boilerplate. Candidates sometimes claim streaming requires client components, when in fact it is Server Components that suspend and stream. Confusing this with the older pages router getServerSideProps pattern is also a signal of shallow experience, since that model blocked rendering until all data resolved.
LIKELY FOLLOW-UPS: The interviewer may ask how you would handle a nested route where both a parent and a child have loading.js files. They might also ask about error.js and how it interacts with Suspense boundaries. Another common pivot is asking whether you can stream from a client component, or how you would opt out of streaming for a specific route. You should also be ready to discuss the fallback waterfall problem and why granular Suspense boundaries beat a single page-level loader.
ONE CONCRETE EXAMPLE: Imagine a dashboard at app/dashboard/page.js that awaits a slow analytics query taking 800 milliseconds. Without streaming, the user stares at a blank screen until the entire HTML arrives. By adding app/dashboard/loading.js that exports a skeleton chart, Next.js wraps the page in a Suspense boundary automatically. The server sends the layout, sidebar, and skeleton within 50 milliseconds. When the query resolves, Next.js streams the remaining HTML and a tiny inline script that swaps the skeleton for the real chart. The user perceives the page as instant, and Core Web Vitals improve because the browser can paint the shell and hydrate incrementally.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.