-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
await blocks unnecessarily unmount and remount their children when the promise changes #8459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The bug only appears with the |
I wrote a small component to use instead of the native <script>
const PENDING = {};
let data = PENDING;
let error = PENDING;
export let promise;
async function onChange() {
[data, error] = await Promise.race([promise, PENDING]).then(
d => [d, PENDING],
e => [PENDING, e],
);
if (data === PENDING && error === PENDING) promise.then(onChange, onChange)
}
$: onChange(promise)
</script>
{#if data !== PENDING}
<slot {data} />
{:else if error !== PENDING}
<slot name="error" {error} />
{:else}
<slot name="pending"/>
{/if} It can be used like so <Await {promise} let:data>
Resolved with {data}
<div slot="pending">Pending...</div>
<div slot="error" let:error>Error: {error}</div>
</Await> |
The current behaviour isn't buggy per se, but it probably would be better to delay the update by a single microtask when changing from one promise to another, in case the latter resolves in that window. Adding the 5.0 milestone so we can review (it is technically a breaking change so would need to happen in a major) |
After looking into this, I'm not sure delaying by a microtask gives us anything. This is a bit like a key block in that the promise is different, so we unmount and remount. I think the existing behaviour actually makes sense here. |
Maybe it's just me (and the 5 people that upvoted this issue), but I found the current behavior impractical. The way it manifests in applications is most often with intempestive loading spinners and unneeded backend requests being made. Fixing this would, I think, just make applications snappier in most cases, and I don't see any obvious downside to it. |
Let me take another look at what we can do then. |
Here's a Svelte 5 copy of the original REPL, showing that the bug has indeed been fixed in Svelte 5: |
Describe the bug
When the promise of an
{#await ... }
block changes from a resolved Promise to another resolved Promise, svelte unnecessarily unmounts and then remounts all the contents of the "then" fragment of the await block.Reproduction
https://svelte.dev/repl/b70b678cc4304ccdac16419e6a979168?version=3.58.0
Here, I wouldn't expect ShowValue to be unmounted and remounted when the buttons are clicked.
In more complex cases, when
ShowValue
is expensive to mount (when it has to do many DOM operations, for instance), this becomes a performance problem.Logs
No response
System Info
Tested in svelte 3.58.0
Severity
annoyance
The text was updated successfully, but these errors were encountered: