Skip to content

[CC] Streaming prerender#94044

Draft
lubieowoce wants to merge 2 commits into
canaryfrom
lubieowoce/streaming-prerender
Draft

[CC] Streaming prerender#94044
lubieowoce wants to merge 2 commits into
canaryfrom
lubieowoce/streaming-prerender

Conversation

@lubieowoce
Copy link
Copy Markdown
Member

@lubieowoce lubieowoce commented May 22, 2026

Replaces prerender with an appropriately tweaked renderToReadableStream so we can get the results streamingly (and see what was emitted in each stage of the prerender). This will be used in #93801 (when i stack it properly)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Failing test suites

Commit: 7e9b881 | About building and testing Next.js

pnpm test-start test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts (job)

  • Cache Components Errors > Build With --prerender-debug > IO accessed in Client Components > should error the build if IO is accessed in a Client Component (DD)
Expand output

● Cache Components Errors › Build With --prerender-debug › IO accessed in Client Components › should error the build if IO is accessed in a Client Component

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `Cache Components Errors Build With --prerender-debug IO accessed in Client Components should error the build if IO is accessed in a Client Component 1`

- Snapshot  - 8
+ Received  + 6

@@ -7,19 +7,17 @@
    - Provide a placeholder with `<Suspense fallback={...}>` around the data access
    - If the runtime data is `params` and they're known, prerender them with `generateStaticParams`
    - Set `export const instant = false` to allow a blocking route

  Learn more: https://nextjs.org/docs/messages/blocking-route
-     at Client (webpack:///app/client-awaited-io/client.tsx:6:19)

  at Page (../webpack:/app/client-awaited-io/page.tsx:5:10)
  -   4 |
  +   3 |
  -   5 | export function Client({ io }: { io: Promise<string> }) {
  +   4 | export default async function Page() {
  - > 6 |   const data = use(io)
  -     |                   ^
  + > 5 |   return <Client io={setTimeout(100, 'Hello, Dave!')} />
  +     |          ^
  -   7 |   return <div>Data: {data}</div>
  -   8 | }
  +   6 | }
  -   9 |
  +   7 |
    To debug the issue, start the app in development mode by running `next dev`, then open "/client-awaited-io" in your browser to investigate the error.
    Error occurred prerendering page "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error
    > Export encountered errors on 1 path:
    	/client-awaited-io/page: /client-awaited-io"
  at Object.toMatchInlineSnapshot (e2e/app-dir/cache-components-errors/cache-components-errors.test.ts:7362:30)

pnpm test-start-turbo test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts (turbopack) (job)

  • Cache Components Errors > Build With --prerender-debug > IO accessed in Client Components > should error the build if IO is accessed in a Client Component (DD)
Expand output

● Cache Components Errors › Build With --prerender-debug › IO accessed in Client Components › should error the build if IO is accessed in a Client Component

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `Cache Components Errors Build With --prerender-debug IO accessed in Client Components should error the build if IO is accessed in a Client Component 1`

- Snapshot  - 8
+ Received  + 6

@@ -7,19 +7,17 @@
    - Provide a placeholder with `<Suspense fallback={...}>` around the data access
    - If the runtime data is `params` and they're known, prerender them with `generateStaticParams`
    - Set `export const instant = false` to allow a blocking route

  Learn more: https://nextjs.org/docs/messages/blocking-route
-     at Client (app/client-awaited-io/client.tsx:6:19)

  at Page (../app/client-awaited-io/page.tsx:5:10)
  -   4 |
  +   3 |
  -   5 | export function Client({ io }: { io: Promise<string> }) {
  +   4 | export default async function Page() {
  - > 6 |   const data = use(io)
  + > 5 |   return <Client io={setTimeout(100, 'Hello, Dave!')} />
  -     |                   ^
  -   7 |   return <div>Data: {data}</div>
  -   8 | }
  +     |          ^
  +   6 | }
  -   9 |
  +   7 |
    To debug the issue, start the app in development mode by running `next dev`, then open "/client-awaited-io" in your browser to investigate the error.
    Error occurred prerendering page "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error
    > Export encountered errors on 1 path:
    	/client-awaited-io/page: /client-awaited-io"
  at Object.toMatchInlineSnapshot (e2e/app-dir/cache-components-errors/cache-components-errors.test.ts:7303:30)

@lubieowoce lubieowoce force-pushed the lubieowoce/streaming-prerender branch 2 times, most recently from 6eb8861 to 75cf43c Compare May 22, 2026 13:27
@github-actions
Copy link
Copy Markdown
Contributor

Stats from current PR

🔴 1 regression

Metric Canary PR Change Trend
node_modules Size 506 MB 507 MB 🔴 +69.8 kB (+0%) ▁████
📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 811ms 812ms █████
Cold (Ready in log) 799ms 797ms ██▇██
Cold (First Request) 1.248s 1.253s ▃█▃▇▄
Warm (Listen) 811ms 811ms █████
Warm (Ready in log) 797ms 799ms █████
Warm (First Request) 625ms 628ms ▆▇▅█▇
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 809ms 810ms ▁████
Cold (Ready in log) 778ms 780ms ▆▇█▇▇
Cold (First Request) 3.204s 3.242s ▆▆▆▃▃
Warm (Listen) 809ms 810ms █▄▄▄▄
Warm (Ready in log) 779ms 780ms █▃▄▄▃
Warm (First Request) 3.247s 3.257s █▂▂▁▁

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.799s 4.760s ▄█▄█▅
Cached Build 4.790s 4.780s ▄█▆█▆
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 23.727s 23.698s █▂▂▁▁
Cached Build 23.608s 23.613s █▁▁▁▁
node_modules Size 506 MB 507 MB 🔴 +69.8 kB (+0%) ▁████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles
Canary PR Change
01j15blnuk32i.js gzip 152 B N/A -
02w0a6jygl3xb.js gzip 65.6 kB N/A -
04hm05ar7kldw.js gzip 5.73 kB N/A -
0cm7r3mu7_5if.js gzip 153 B N/A -
0cz1d0mv5g_q7.js gzip 39.4 kB 39.4 kB
0dj46kukqg96u.js gzip 13.9 kB N/A -
0dvitrl5zg37g.js gzip 8.82 kB N/A -
0sf7ysou-72zd.js gzip 8.71 kB N/A -
0yr3zdx3hcb1a.js gzip 160 B N/A -
12qe1n53ey9y2.js gzip 156 B N/A -
157abun3hwc_s.js gzip 10.3 kB N/A -
19_4xrr36l6mk.js gzip 169 B N/A -
1elt1qium-r2m.css gzip 115 B 115 B
1fjyrqlrh6kyh.js gzip 155 B N/A -
1jpaub6y8xlfr.js gzip 2.3 kB N/A -
1kwmjlg5_u25-.js gzip 155 B N/A -
1ot0mvscrc_uf.js gzip 233 B N/A -
1rsianesvgn5k.js gzip 157 B N/A -
2_m3xv2uq3sjc.js gzip 1.46 kB N/A -
2159g6lh7dqu1.js gzip 158 B N/A -
216pas6amn7dj.js gzip 160 B N/A -
24y34mwgrkqp4.js gzip 8.78 kB N/A -
24ye66xi7wyk6.js gzip 156 B N/A -
25xpv8oncgk4t.js gzip 50.5 kB N/A -
2c-fd4y1zozz8.js gzip 8.79 kB N/A -
2d7416h_xd36x.js gzip 8.71 kB N/A -
2g21ny1t2kw37.js gzip 7.61 kB N/A -
2lyuhit6rn8fy.js gzip 9.44 kB N/A -
2p66c440qgxee.js gzip 154 B N/A -
2q0gr8wfr3jwl.js gzip 8.77 kB N/A -
2t9e75oz6r0zp.js gzip 8.76 kB N/A -
2uku_olcn15b7.js gzip 8.79 kB N/A -
30r8mm-46bdqy.js gzip 220 B 220 B
35rd0xtnx16e0.js gzip 157 B N/A -
3c1jdxkzlb8oq.js gzip 12.9 kB N/A -
3inab2jybr4k9.js gzip 450 B N/A -
3jkm5tdjvaf_q.js gzip 13.1 kB N/A -
3mt67agm5wp40.js gzip 10.6 kB N/A -
3saabek4kohwi.js gzip 10 kB N/A -
4189xmby9yu1p.js gzip 13.6 kB N/A -
42jx7q9s1x0ul.js gzip 70.9 kB N/A -
turbopack-03..2hjt.js gzip 4.18 kB N/A -
turbopack-04..ndg_.js gzip 4.2 kB N/A -
turbopack-05..0h70.js gzip 4.2 kB N/A -
turbopack-1-..pv_m.js gzip 4.2 kB N/A -
turbopack-14..q6qs.js gzip 4.2 kB N/A -
turbopack-17..6txd.js gzip 4.2 kB N/A -
turbopack-1g..xdpe.js gzip 4.21 kB N/A -
turbopack-2u..23eb.js gzip 4.2 kB N/A -
turbopack-3_..3sjo.js gzip 4.2 kB N/A -
turbopack-39..q47u.js gzip 4.2 kB N/A -
turbopack-3b..q1_t.js gzip 4.2 kB N/A -
turbopack-3h..8i9l.js gzip 4.2 kB N/A -
turbopack-3k..jlo_.js gzip 4.2 kB N/A -
turbopack-3r..j1ku.js gzip 4.2 kB N/A -
0_i7nqgx23st7.js gzip N/A 10 kB -
00oqj5cyd1qzl.js gzip N/A 156 B -
04vzk51e22nt1.js gzip N/A 155 B -
06puhytyxk31p.js gzip N/A 8.82 kB -
0blpf9e4tox42.js gzip N/A 160 B -
0j42f9zonj0wd.js gzip N/A 13 kB -
0m34gln_kt4fg.js gzip N/A 5.73 kB -
0q30qien57zwr.js gzip N/A 50.5 kB -
0rqsmjsof08wr.js gzip N/A 70.9 kB -
0rxy1v89niudo.js gzip N/A 65.6 kB -
0uwwepracw4m6.js gzip N/A 156 B -
1e1_uo-941dw5.js gzip N/A 151 B -
1g3q1ww01thnl.js gzip N/A 2.3 kB -
1hraqxuiymq6v.js gzip N/A 8.79 kB -
1l9un1sl77287.js gzip N/A 1.46 kB -
1mdgcrubwjuap.js gzip N/A 154 B -
1tdu3zflzm2vs.js gzip N/A 161 B -
1y1bm0vc5d282.js gzip N/A 154 B -
2147zgtf14z-q.js gzip N/A 234 B -
23bz3xsg-5-1s.js gzip N/A 8.71 kB -
26x7mybqvrsng.js gzip N/A 157 B -
27441mytv7pbm.js gzip N/A 9.43 kB -
2cjkwjgm1zcfs.js gzip N/A 8.71 kB -
2djalypq0dh9o.js gzip N/A 156 B -
2scd8zaoyb8md.js gzip N/A 8.79 kB -
2st_qs6p_9us0.js gzip N/A 13.1 kB -
2tkfwji1v0cuq.js gzip N/A 169 B -
2zo2exm1d8qj1.js gzip N/A 13.6 kB -
30oszfu8bgqbc.js gzip N/A 13.9 kB -
3ejohxold_h5g.js gzip N/A 155 B -
3f710q6kll2xn.js gzip N/A 7.61 kB -
3hn75zuxly9az.js gzip N/A 10.3 kB -
3hqh7m128tvsn.js gzip N/A 8.77 kB -
3hqti_t-zy1x4.js gzip N/A 449 B -
3mnawenie1flm.js gzip N/A 8.76 kB -
3oaqodtp62mi9.js gzip N/A 155 B -
3ubsozlu6zs38.js gzip N/A 10.6 kB -
43iwfqjnx1cy_.js gzip N/A 8.78 kB -
turbopack-0n..h-sy.js gzip N/A 4.2 kB -
turbopack-0s..5i7m.js gzip N/A 4.2 kB -
turbopack-1_..8o4i.js gzip N/A 4.2 kB -
turbopack-15..p-zi.js gzip N/A 4.18 kB -
turbopack-1n..211-.js gzip N/A 4.2 kB -
turbopack-1u..fdzf.js gzip N/A 4.2 kB -
turbopack-29..omsk.js gzip N/A 4.2 kB -
turbopack-2c..poq6.js gzip N/A 4.2 kB -
turbopack-2p..o93g.js gzip N/A 4.2 kB -
turbopack-2p..ugcb.js gzip N/A 4.2 kB -
turbopack-2t..oq8y.js gzip N/A 4.21 kB -
turbopack-2u..mwnq.js gzip N/A 4.2 kB -
turbopack-35..josz.js gzip N/A 4.2 kB -
turbopack-37..-79w.js gzip N/A 4.2 kB -
Total 469 kB 469 kB ⚠️ +11 B

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 719 B 716 B
Total 719 B 716 B ✅ -3 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 433 B 435 B
Total 433 B 435 B ⚠️ +2 B

📦 Webpack

Client

Main Bundles
Canary PR Change
2258-HASH.js gzip 61.6 kB N/A -
2266-HASH.js gzip 4.69 kB N/A -
3317.HASH.js gzip 169 B N/A -
4866-HASH.js gzip 5.64 kB N/A -
9e302639-HASH.js gzip 62.8 kB N/A -
framework-HASH.js gzip 59.5 kB 59.5 kB
main-app-HASH.js gzip 256 B 251 B 🟢 5 B (-2%)
main-HASH.js gzip 39.9 kB 39.9 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
175fd0fd-HASH.js gzip N/A 62.8 kB -
2596-HASH.js gzip N/A 5.63 kB -
34-HASH.js gzip N/A 61.4 kB -
5691.HASH.js gzip N/A 169 B -
9156-HASH.js gzip N/A 4.68 kB -
Total 236 kB 236 kB ✅ -132 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 181 B 182 B
css-HASH.js gzip 334 B 332 B
dynamic-HASH.js gzip 1.79 kB 1.81 kB
edge-ssr-HASH.js gzip 255 B 255 B
head-HASH.js gzip 351 B 348 B
hooks-HASH.js gzip 385 B 384 B
image-HASH.js gzip 580 B 580 B
index-HASH.js gzip 257 B 259 B
link-HASH.js gzip 2.51 kB 2.52 kB
routerDirect..HASH.js gzip 318 B 319 B
script-HASH.js gzip 387 B 386 B
withRouter-HASH.js gzip 316 B 316 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.99 kB ⚠️ +19 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 276 kB 271 kB 🟢 5 kB (-2%)
Total 403 kB 397 kB ✅ -5.21 kB
Middleware
Canary PR Change
middleware-b..fest.js gzip 620 B 616 B
middleware-r..fest.js gzip 155 B 155 B
middleware.js gzip 44.3 kB 44.7 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 46 kB 46.4 kB ⚠️ +409 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 719 B 717 B
Total 719 B 717 B ✅ -2 B
Build Cache
Canary PR Change
0.pack gzip 4.49 MB 4.49 MB 🟢 8.03 kB (0%)
index.pack gzip 115 kB 114 kB 🟢 1.17 kB (-1%)
index.pack.old gzip 114 kB 114 kB
Total 4.72 MB 4.71 MB ✅ -9.42 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 351 kB 351 kB
app-page-exp..prod.js gzip 195 kB 195 kB
app-page-tur...dev.js gzip 350 kB 351 kB
app-page-tur..prod.js gzip 194 kB 195 kB
app-page-tur...dev.js gzip 347 kB 347 kB
app-page-tur..prod.js gzip 193 kB 193 kB
app-page.run...dev.js gzip 347 kB 347 kB
app-page.run..prod.js gzip 193 kB 193 kB
app-route-ex...dev.js gzip 77.6 kB 77.6 kB
app-route-ex..prod.js gzip 52.9 kB 52.9 kB
app-route-tu...dev.js gzip 77.6 kB 77.6 kB
app-route-tu..prod.js gzip 52.9 kB 52.9 kB
app-route-tu...dev.js gzip 77.2 kB 77.2 kB
app-route-tu..prod.js gzip 52.7 kB 52.7 kB
app-route.ru...dev.js gzip 77.2 kB 77.2 kB
app-route.ru..prod.js gzip 52.7 kB 52.7 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 44.3 kB 44.3 kB
pages-api-tu..prod.js gzip 33.8 kB 33.8 kB
pages-api.ru...dev.js gzip 44.3 kB 44.3 kB
pages-api.ru..prod.js gzip 33.7 kB 33.7 kB
pages-turbo....dev.js gzip 53.7 kB 53.7 kB
pages-turbo...prod.js gzip 39.4 kB 39.4 kB
pages.runtim...dev.js gzip 53.6 kB 53.6 kB
pages.runtim..prod.js gzip 39.4 kB 39.4 kB
server.runti..prod.js gzip 63.1 kB 63.1 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
Total 3.37 MB 3.37 MB ⚠️ +2.36 kB
📝 Changed Files (8 files)

Files with changes:

  • app-page-exp..ntime.dev.js
  • app-page-exp..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page.runtime.dev.js
  • app-page.runtime.prod.js
View diffs
app-page-exp..ntime.dev.js
failed to diff
app-page-exp..time.prod.js

Diff too large to display

app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page.runtime.dev.js
failed to diff
app-page.runtime.prod.js

Diff too large to display

📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/75cf43c79ccdf35634a407ae4e28d6f8b89c1e54/next

Commit: 75cf43c

@lubieowoce lubieowoce force-pushed the lubieowoce/streaming-prerender branch from 75cf43c to 7e9b881 Compare May 22, 2026 16:14
acdlite pushed a commit that referenced this pull request May 25, 2026
Squashed server-only diff from:
  - #94044  Streaming prerender
  - #93801  Rewinding app shells

This commit is a placeholder on the stack so we can develop and test the
client-side rewinding integration that lands in the commit above. It gets
regenerated from Janka's latest each time we re-sync; do not edit by hand.

For now this uses only the fallback-stage branch as source because its
app-render.tsx version supersedes streaming-prerender's (the smaller
streaming-prerender files are byte-identical to fallback-stage's).
Replaces the forceOmitParams hanging-promise mechanism from canary with
the abort-before-params approach Janka builds on.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant