fix(app-router): respect reactMaxHeadersLength for preload Link header (#1552)#1841
Conversation
|
/bigbonk review for issues |
commit: |
|
Review:
|
|
Review posted to PR #1841. Summary of findings: Review summaryThe PR is correct and well-scoped. I verified:
Non-blocking observations posted:
No correctness bugs or regressions found. The documented RSC-preload caveat is honest and appropriately deferred. |
… buildAppPageLinkHeader Address review feedback on #1841: - Order React preload hints before font preloads so render-critical entries survive a tight reactMaxHeadersLength cap. - Rename the buildAppPageHtmlResponse option to linkHeader (it now carries the combined header, not just fonts). - Add unit coverage for buildAppPageLinkHeader (cap, 0-disables, ordering, whole-entry truncation).
|
Thanks for the review. Addressed the actionable items:
/bigbonk review for issues |
Re-review: addressed items verifiedRe-reviewed after the three follow-up commits ( 1. Test gap — resolved
2. Duplicated
|
|
Posted the re-review to PR #1841. All four items from the prior review are resolved and verified:
Additional verification:
No correctness issues found — LGTM. |
Problem
reactMaxHeadersLength(the cap on the total length of the preloadLinkheader React inlines during App Router SSR) was not respected — vinext never forwarded the option into the React renderer. Fixes #1552.Fix
Thread
reactMaxHeadersLengthfromnext.configthrough the App Router render pipeline and into React'srenderToReadableStream:config/next-config.ts): acceptreactMaxHeadersLength, default to6000(matching Next.js'sdefaultConfig).entries/app-rsc-entry.ts): embed the resolved value and pass it through the page dispatch.app-page-dispatch.ts→app-page-render.ts→app-page-stream.ts→app-ssr-entry.ts): forward the value, wire React'sonHeaders+maxHeadersLengthso React caps and emits its preloadLinkheader.0disables emission entirely (noonHeaderswired, noLinkheader set).buildAppPageLinkHeader): combine vinext's font preloadLinkheader with React's emittedLinkheader and cap the combined value toreactMaxHeadersLength, dropping whole entries once the limit is exceeded (mirrors React's behavior, where every preload flows through a single cappedonHeaders).Test
tests/nextjs-compat/react-max-headers-length.test.ts(ported fromtest/e2e/app-dir/react-max-headers-length) verifies the cap contract against the emittedLinkheader:0emits no header, small caps truncate to whole entries, larger caps emit more entries, and the default stays within 6000. Backed by a minimal route fixture underapp-basicwhosereactMaxHeadersLengthis env-driven (matching the upstreamTEST_REACT_MAX_HEADERS_LENGTHswitch).Caveat
vinext's App Router SSR currently surfaces its preload
Linkheader from the font pipeline. RSC-originatedReactDOM.preload()hints from Server Components flow through the embedded Flight stream and are applied client-side rather than captured by the SSR FizzonHeaderspass (the app tree renders behind the Flight-streamSuspense, so user preloads resolve after the shell completes and React'sonHeadershas already fired). Making those preloads reach the SSR header is a separate, larger change; this PR forwards the config option into the renderer and makes the emittedLinkheader respectreactMaxHeadersLength, which is the behavior the issue calls for.Closes #1552