Skip to content

Conversation

@Rich-Harris
Copy link
Member

@Rich-Harris Rich-Harris commented Oct 26, 2025

Extremely WIP. The tests pass, but it's an illusion — there's much still to do.

This will enable out-of-order rendering, which is to say that in a situation like this, where something is awaited in the <script>...

<!-- +layout.svelte --> <script>  import { getUser } from '$lib/data.remote';   let { children } = $props();   const user = $derived(await getUser()); </script> <nav> {#if user} <p>hello {user.name}!</p> {:else} <a href="/login">log in</a> {/if} </nav> <main> {@render children()} </main>

...the component's contents can begin rendering immediately — async work in {@render children()} needn't wait for the unrelated async work in the layout.

The basic strategy is this: any statements or declarations containing await — or any statements or declarations that follow them — are wrapped in async functions that run sequentially. So this...

var a = 1; await sleep(); var b = 2; await sleep(); var c = 3;

...becomes this:

var a = 1; var b, c; var $$promises = $.run([ () => sleep(), () => b = 2, () => sleep(), () => c = 3 ]);

Any parts of the template that depend on b must wait for $$promises[1] to resolve, while any that depend on c must wait for $$promises[3].

Things still to do:

  • equivalent of $.run in SSR (right now it's a noop)
  • fix some hydration bugs that don't show up in tests but are definitely there
  • handle corner cases, like x = $state() followed by x = {...} — anything that depends on x must wait for the latter promise to resolve. This means analysing statements for mutations or function calls that could cause mutations; it may be the case that in some cases we need to deopt and await the final promise
  • tidy up the code

Follow-up work:

  • reorder statements? So far I didn't do this, because it's potentially dangerous. But it would be nice if we could — for example — yoink $derived expressions as high as they'll go and run them in parallel

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
@Rich-Harris Rich-Harris marked this pull request as draft October 26, 2025 02:36
@Rich-Harris Rich-Harris marked this pull request as ready for review October 26, 2025 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant