Skip to content

Conversation

Rich-Harris
Copy link
Member

We missed a crucial detail in #16784 — content after an async block isn't correctly hydrated, because the hydration state gets corrupted.

Conceptually the fix is very straightforward. We need to wrap each async block in hydration markers (<!--[--> and <!--]-->), and when encountering an async block, stash the hydrate_node, skip ahead to the <!--]-->, hydrate the next thing, and then restore hydrate_node when the async block is ready to proceed. I'd like to do a bit more testing before marking this ready for review though.

This isn't a complete fix, because hydration will update the DOM piecemeal. That means that if you have something like this...

{#if await condition}
  <p>hello from the {browser ? 'browser' : 'server'}</p>
{/if}

<p>hello again from the {browser ? 'browser' : 'server'}</p>

...the second paragraph will update immediately, while the second one will update once condition resolves. That's not what we want — we want those updates to be synchronized within a boundary. That will involve a little bit more footwork that's outside the scope of this PR, but which we'll get to soon.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

Copy link

changeset-bot bot commented Sep 18, 2025

🦋 Changeset detected

Latest commit: 994583c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@16797

@Rich-Harris
Copy link
Member Author

This turned out to be a bit of a rabbit hole — we're not currently handling await in element attributes at all during SSR, and we haven't been handling <Foo {...await spread()}> in the CSR case either.

I think that stuff is basically fixed though there's still some stuff I want to look at tomorrow:

  • would be nice to DRY out the optimiser stuff
  • we're handling spreads all wrong for <select> and <option> in SSR — we're repeating the expression instead of storing it. We should have $$renderer.select and $$renderer.option methods for handling this stuff
  • we might not need the additional hydration markers around async blocks? IIUC they always wrap blocks which should already have those markers. Certainly in some cases
  • shuffle the build_attribute_value arguments around — transform is required, but the two booleans are optional
  • more tests still ({#key await blah} etc)

Once all that's done, we can get to work on the coordinated updates stuff

@Rich-Harris Rich-Harris marked this pull request as ready for review September 19, 2025 22:45
@Rich-Harris
Copy link
Member Author

Okay, done — hydration works with async blocks, async attributes are now supported outside a pending boundary (whether spread or not), <select> and <option> are more robust (no duplicated spread code), and the Renderer internals are much simpler (no compact method etc)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall looks great

@Rich-Harris Rich-Harris merged commit 5c09035 into main Sep 19, 2025
18 checks passed
@Rich-Harris Rich-Harris deleted the async-hydration branch September 19, 2025 23:36
@github-actions github-actions bot mentioned this pull request Sep 19, 2025
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