Preserve the rendered shell on synchronous prerender abort #37853

Open
gnoff opened 7:20pm on October 14, 2026 wants to merge 552 Ξ” into facebook/react main from
jstory/fizz-sync-abort-precise-postpone
gnoff authored
of work between October 14 and October 15
Diff Delta:
552
About 75 Diff Delta/hour
Classified as:  General

gnoff's Description of Work

37709 showed that a synchronous prerender abort can discard a retried task's rendered shell, then resume only an inner slot. #37710 addressed the missing markup by postponing the whole task, but that could overlap replay paths from child tasks; #37852 reverted that approach.

Preserve the parent segment and continue rendering its text and host elements after abort. When a component or other render callback returns after abort, discard its children and track a postponed hole at that node. This includes function and class components, lazy and forward-ref components, Context.Consumer render props, iterables, and thenables. Already-created arrays are read normally; getters and host prop serialization follow React's render-purity rules. The new path applies to content segments without an assigned replay ID; SuspenseList rows retain their separate completion handling.

This restores the tests from #37710, #37850, and #37851 and adds coverage for indexed retries, static host children after abort, synchronous and async iterators and thenables that abort while producing a child, forward refs that abort during render, render-phase updates, nested fallbacks, and repeated aborts. ReactDOMFizzStaticBrowser passes in development and production on both stable and experimental channels; the regular Fizz server and static Node suites, lint, and a full Flow check with the worktree included pass.

2 total changed files
Loading changes...
Loading changes...
End of PR:
All files reviewed β€” nice work, champ! πŸ’ͺ