When draft mode is enabled, Next.js blocks the first byte of the response
until every 'use cache' helper has resolved, even if those helpers are
wrapped in <Suspense> and the page has no other awaits.
pnpm install
pnpm build
pnpm startIn app/draft-mode-ttfb/page.tsx:
- The page calls
await draftMode()at the top (special-cased; should not deopt). - When draft is enabled, the body is two sibling
<Suspense>boundaries wrapping async children that fetch data. - The cached body (
CachedHomeBody) uses'use cache'and should hit on every request after the first. - The preview body (
PreviewHomeBody) is the only one doing fresh, uncached work.
We expected:
- TTFB ~10ms — the
<PageShell>and Suspense fallbacks flush immediately. - The cached body streams in shortly after (cache HIT).
- The preview body streams in after ~1s (the
simulateApi()sleep).
What actually happens:
- TTFB is ~1000ms — the entire response, including the
<head>, is buffered until the cached body resolves. - The Suspense fallbacks are present in the final HTML alongside the resolved content, confirming Suspense fired but did not enable early flush.
The only enabled flag relevant to this repro:
const nextConfig: NextConfig = {
cacheComponents: true,
};