Skip to content

Commit 7a08d9b

Browse files
committed
flesh out await_reactivity_loss warning
1 parent c028371 commit 7a08d9b

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

documentation/docs/98-reference/.generated/client-warnings.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,41 @@ function add() {
3737
### await_reactivity_loss
3838
3939
```
40-
Detected reactivity loss
40+
Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`
4141
```
4242

43-
TODO
43+
Svelte's signal-based reactivity works by tracking which bits of state are read when a template or `$derived(...)` expression executes. If an expression contains an `await`, Svelte transforms it such that any state _after_ the `await` is also tracked — in other words, in a case like this...
44+
45+
```js
46+
let total = $derived(await a + b);
47+
```
48+
49+
...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution.
50+
51+
This does _not_ apply to an `await` that is not 'visible' inside the expression. In a case like this...
52+
53+
```js
54+
async function sum() {
55+
return await a + b;
56+
}
57+
58+
let total = $derived(await sum());
59+
```
60+
61+
...`total` will depend on `a` (which is read immediately) but not `b` (which is not). The solution is to pass the values into the function:
62+
63+
```js
64+
async function sum(a, b) {
65+
return await a + b;
66+
}
67+
68+
let total = $derived(await sum(a, b));
69+
```
4470
4571
### await_waterfall
4672
4773
```
48-
An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app.
74+
An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
4975
```
5076
5177
TODO

packages/svelte/messages/client-warnings/warnings.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,39 @@ function add() {
3232
3333
## await_reactivity_loss
3434
35-
> Detected reactivity loss
35+
> Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`
3636
37-
TODO
37+
Svelte's signal-based reactivity works by tracking which bits of state are read when a template or `$derived(...)` expression executes. If an expression contains an `await`, Svelte transforms it such that any state _after_ the `await` is also tracked — in other words, in a case like this...
38+
39+
```js
40+
let total = $derived(await a + b);
41+
```
42+
43+
...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution.
44+
45+
This does _not_ apply to an `await` that is not 'visible' inside the expression. In a case like this...
46+
47+
```js
48+
async function sum() {
49+
return await a + b;
50+
}
51+
52+
let total = $derived(await sum());
53+
```
54+
55+
...`total` will depend on `a` (which is read immediately) but not `b` (which is not). The solution is to pass the values into the function:
56+
57+
```js
58+
async function sum(a, b) {
59+
return await a + b;
60+
}
61+
62+
let total = $derived(await sum(a, b));
63+
```
3864
3965
## await_waterfall
4066
41-
> An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app.
67+
> An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
4268
4369
TODO
4470

packages/svelte/src/internal/client/runtime.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,10 @@ export function get(signal) {
875875
var was_read = from_async_derived.deps !== null && from_async_derived.deps.includes(signal);
876876

877877
if (!tracking && !was_read) {
878-
w.await_reactivity_loss();
878+
w.await_reactivity_loss(/** @type {string} */ (signal.label));
879+
880+
// eslint-disable-next-line no-console
881+
console.warn(get_stack('TracedAt'));
879882
}
880883
}
881884

packages/svelte/src/internal/client/warnings.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,24 @@ export function assignment_value_stale(property, location) {
1919
}
2020

2121
/**
22-
* Detected reactivity loss
22+
* Detected reactivity loss when reading `%name%`. This happens when state is read in an async function after an earlier `await`
23+
* @param {string} name
2324
*/
24-
export function await_reactivity_loss() {
25+
export function await_reactivity_loss(name) {
2526
if (DEV) {
26-
console.warn(`%c[svelte] await_reactivity_loss\n%cDetected reactivity loss\nhttps://svelte.dev/e/await_reactivity_loss`, bold, normal);
27+
console.warn(`%c[svelte] await_reactivity_loss\n%cDetected reactivity loss when reading \`${name}\`. This happens when state is read in an async function after an earlier \`await\`\nhttps://svelte.dev/e/await_reactivity_loss`, bold, normal);
2728
} else {
2829
console.warn(`https://svelte.dev/e/await_reactivity_loss`);
2930
}
3031
}
3132

3233
/**
33-
* An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app.
34+
* An async value (%location%) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
3435
* @param {string} location
3536
*/
3637
export function await_waterfall(location) {
3738
if (DEV) {
38-
console.warn(`%c[svelte] await_waterfall\n%cAn async value (${location}) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app.\nhttps://svelte.dev/e/await_waterfall`, bold, normal);
39+
console.warn(`%c[svelte] await_waterfall\n%cAn async value (${location}) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app\nhttps://svelte.dev/e/await_waterfall`, bold, normal);
3940
} else {
4041
console.warn(`https://svelte.dev/e/await_waterfall`);
4142
}

0 commit comments

Comments
 (0)