Skip to content

fix: clean up owned streamed hydration ranges on unmount - #5314

Closed
kasperrt wants to merge 1 commit into
preactjs:mainfrom
kasperrt:fix/streamed-hydration-range-ownership
Closed

kasperrt wants to merge 1 commit into
preactjs:mainfrom
kasperrt:fix/streamed-hydration-range-ownership

Conversation

@kasperrt

Copy link
Copy Markdown

A hydrated streamed Suspense boundary can retain its server fallback after its component unmounts. The reserved DOM range is not represented by ordinary child VNodes. A second problem appears when a persistent sibling suspends again: the insertion cursor can remain inside its marker range, causing new sibling content to disappear when that boundary resumes.

Retain the opening marker on the owning component, remove only its balanced range during unmount, and use the closing marker as the insertion cursor on re-suspension. Keep markers during successful resume so streaming/hydration continues to find them. Lifecycle callbacks and ordinary child cleanup still run before range removal. No observer, polling, selector-based cleanup or renderer copy is added.

Reproduction: stream a persistent root boundary beside a route boundary, hydrate while both promises remain unresolved, then replace the route with a destination heading. Resolve the root and original route afterward. The destination must remain, abandoned fallback/resolved content must be absent, and the root input/focus must survive. The added tests reproduce this directly in Preact without a router.

Validation:

  • Unchanged 11.0.1: all three added regressions fail; 40 existing tests in the file pass.
  • Candidate: 43/43 hydration tests pass.
  • Full minified suite on current main: 107 files pass, 1,402 tests pass, 11 existing skips.
  • Lint and JavaScript typechecking pass.
  • Ten separately built production SSR/router fixtures pass with the candidate's official build output, covering abandonment, settlement races, return, independent/nested boundaries, root revalidation, history and interruption. The alias used for that isolated experiment is not a consumer/package workaround.

This is a proposed upstream fix; no downstream release containing a patched renderer has been published. Broader upstream review is requested for marker ownership and unmount ordering.

@github-actions

Copy link
Copy Markdown

📊 Tachometer Benchmark Results

Summary

A summary of the benchmark results will show here once they finish.

Results

The full results of your benchmarks will show here once they finish.

tachometer-reporter-action v2 for CI

@JoviDeCroock

Copy link
Copy Markdown
Member

We recognize that LLM's have become an integral tool for many users, however when using LLMs to help write issues or pull requests, disclose this. Transparency preserves the collaborative integrity that makes open-source communities work. It's the difference between "I used AI to help structure this bug report" (honest, helpful) and silently passing off generated content as your own analysis (deceptive, counterproductive). We as maintainers want to engage with humans rather than LLM-generated messages, put time in your issue report and that will be reflected back.

Examples of unacceptable behavior by participants include:

  • The use of sexualized language or imagery and unwelcome sexual attention or advances
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or electronic address, without explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting
  • Writing an issue, pull request or comments through an LLM without disclosing this

Code of Conduct

At this point, breaches of the CoC result in an instant close.

@kasperrt
kasperrt deleted the fix/streamed-hydration-range-ownership branch October 17, 2026 16:21
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.

2 participants