Home JavaScript No Loading UI in Next.js 16 — Users Watched a White Screen for 8 Seconds
Beginner 6 min · July 12, 2026
Loading UI, Streaming, and Suspense Boundaries in Next.js 16

No Loading UI in Next.js 16 — Users Watched a White Screen for 8 Seconds

Without loading.js and Suspense boundaries, Next.js 16 blocks the entire page on the slowest data fetch.

N
Naren Founder & Principal Engineer

20+ years shipping production JavaScript and front-end systems at scale. Notes here come from systems that actually shipped.

Follow
Production
production tested
July 19, 2026
last updated
2,466
articles · all by Naren
Before you start⏱ 20 min
  • React fundamentals
  • Next.js App Router
  • Basic understanding of Server Components
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Without loading.js, Next.js waits for ALL data fetches in a page before sending anything to the browser — slowest fetch dictates Time to First Byte
  • loading.js creates instant Suspense boundaries at the route segment level, streaming in content as each fetch resolves
  • Use granular Suspense boundaries inside layouts to stream independent sections independently
  • The React 19 use() hook inside Suspense enables per-component streaming without loading.js boilerplate
  • Streaming doesn't eliminate server work — it eliminates waiting for ALL work before sending the first byte
✦ Definition~90s read
What is Loading UI, Streaming, and Suspense Boundaries in Next.js 16?

Next.js streaming and loading UI is a rendering architecture that delivers HTML progressively from the server to the browser using Suspense boundaries. Instead of waiting for all data fetches to complete before sending any content (traditional SSR), streaming sends the page shell immediately and fills in each section as its data resolves. loading.tsx is a file convention that creates an automatic Suspense boundary for a route segment, rendering a loading state instantly while the page fetches its data.

Imagine a restaurant kitchen that doesn't serve anything until every order across all tables is ready.

Granular Suspense boundaries inside pages allow independent components to stream at their own pace, so a slow API call in one section doesn't delay the rest of the page. This significantly improves perceived performance and Time to First Byte while maintaining SEO benefits of server-side rendering.

Plain-English First

Imagine a restaurant kitchen that doesn't serve anything until every order across all tables is ready. Table 1's salad sits waiting for Table 10's well-done steak. That's your Next.js page without loading UI. Streaming is like serving each table's food as it's ready — the salad comes immediately, the steak arrives when it's done. The customer (user) sees progress instead of staring at an empty table.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

You shipped a dashboard page with three data-fetching components: a user profile (fast, 50ms), a sales chart (500ms), and a monthly report from a legacy API (8 seconds). You open the page. White screen. Eight seconds later, everything renders at once. Your users? They navigated away after 3 seconds.

This is the default behavior in Next.js 16: a page renders only after ALL its data dependencies resolve. The server waits for the slowest fetch, then sends the complete HTML. No progressive loading. No partial rendering. Just a blank screen that suddenly fills.

Next.js has had loading.js for route-level loading states since version 13, and Suspense boundaries for granular streaming since React 18. But most teams either skip loading.js entirely ("it adds complexity") or put a single spinner at the top level (which defeats the purpose). The result: users see either nothing or a generic loading state that doesn't communicate which part of the page is actually loading.

By the end of this guide, you'll know how to use loading.js for instant route-level loading states, Suspense boundaries with fallbacks for per-component streaming, and the new React 19 use() hook to trigger Suspense inside components without loading.tsx boilerplate. Your slow API call won't block your fast components anymore.

How Next.js Streaming Actually Works (It's Not What Most Devs Think)

Streaming in Next.js isn't about sending data chunks over a WebSocket. It's about server-side HTML rendering with Suspense boundaries. Here's the mechanic: when Next.js encounters a Suspense boundary during server-side rendering, it immediately sends the fallback UI (the loading state) as HTML, then continues rendering the rest of the page. When the data inside the boundary resolves, it sends a replacement chunk via an inline

⚙ Quick Reference
8 commands from this guide
FileCommand / CodePurpose
appdashboardloading.tsxexport default function DashboardLoading() {loading.tsx
appdashboardpage.tsxexport default function DashboardPage() {Granular Suspense Boundaries
componentsDataComponent.tsxfunction DataComponent({ promise }: { promise: Promise }) {The React 19 use() Hook
appdashboardpage.tsxexport default async function DashboardPage() {Parallel Data Fetching vs. Sequential
appdashboardpage.tsxfunction DashboardPage() {Error Handling Inside Suspense Boundaries
appdashboardpage.tsxexport const experimental_ppr = trueStreaming and Caching
componentsReport.tsxexport default async function Report() {Measuring Streaming Performance Correctly
appdashboardpage.tsxexport const dynamic = 'force-dynamic'A Complete Streaming Architecture for Production

Key takeaways

1
loading.tsx at every route segment with data fetches
it's the simplest and highest-impact performance improvement
2
Granular Suspense boundaries inside pages for independently-streaming components
slow sections don't block fast ones
3
Critical SEO content must render outside Suspense boundaries
Googlebot may not wait for streamed content
4
React 19 use() hook triggers Suspense from synchronous components, replacing async wrapper components
5
Parallel data fetching + Suspense boundaries = best performance. Sequential fetches + no Suspense = worst performance
6
PPR (Partial Prerendering) combines cached static shell with streaming dynamic content
enable it for mixed-content routes
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does streaming work in Next.js App Router, and what mechanism allows...
Q02SENIOR
Explain loading.tsx and how it differs from creating a custom Suspense b...
Q03SENIOR
How would you architect a Next.js 16 dashboard page that has fast nav da...
Q04SENIOR
What is the React 19 use() hook and how does it relate to Suspense bound...
Q01 of 04SENIOR

How does streaming work in Next.js App Router, and what mechanism allows Suspense boundaries to render independently?

ANSWER
Streaming in Next.js works through server-side rendering with Suspense boundaries. When the server encounters a Suspense boundary during rendering, it immediately sends the fallback UI as HTML. Meanwhile, the async Server Component inside the boundary fetches its data. When the data resolves, the server sends a replacement chunk via an inline <script> tag that React on the client uses to replace the fallback with the real content. Each Suspense boundary is an independent render unit — the server processes them concurrently, and the client applies updates incrementally. This is possible because React 18+ supports selective hydration and streaming HTML via renderToPipeableStream or renderToReadableStream.
FAQ · 7 QUESTIONS

Frequently Asked Questions

01
What's the difference between loading.tsx and Suspense boundaries?
02
Does streaming work with Client Components?
03
Will my page SEO suffer if I put content inside Suspense?
04
How does streaming interact with ISR (Incremental Static Regeneration)?
05
Can I have nested Suspense boundaries?
06
What happens if I use loading.tsx AND Suspense boundaries in the same page?
07
Does streaming work with HTTP/1.1?
N
Naren Founder & Principal Engineer

20+ years shipping production JavaScript and front-end systems at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 19, 2026
last updated
2,466
articles · all by Naren
🔥

That's Next.js. Mark it forged?

6 min read · try the examples if you haven't

Previous
Image and Font Optimization in Next.js 16
26 / 56 · Next.js
Next
Error Handling in Next.js 16: error.js, not-found.js, and Global Errors