@ -51,7 +51,18 @@ In essence, `$derived(expression)` is equivalent to `$derived.by(() => expressio
Anything read synchronously inside the `$derived` expression (or `$derived.by` function body) is considered a _dependency_ of the derived state. When the state changes, the derived will be marked as _dirty_ and recalculated when it is next read.
To exempt a piece of state from being treated as a dependency, use [`untrack`](svelte#untrack).
In async derived expressions/functions, only values read **synchronously during evaluation** are tracked automatically (reads that happen after an `await` are not). If you need a value to be a dependency, read it before awaiting (or split it out into its own derived):
```svelte
<script>
const slug = $derived(params.slug); // tracked
const post = $derived(await getPost(slug)); // uses tracked slug
</script>
```
In `$derived(await getPost(params.slug))`, `params.slug` is evaluated before the `await` yields, so it is part of the synchronous evaluation and can be tracked as a dependency.
Avoid relying on `await` as a way to prevent tracking — if you intentionally want to exclude a value from being treated as a dependency, use [`untrack`](svelte#untrack) instead.
@ -65,18 +65,22 @@ Svelte will do as much asynchronous work as it can in parallel. For example if y
...both functions will run at the same time, as they are independent expressions, even though they are _visually_ sequential.
This does not apply to sequential `await` expressions inside your `<script>` or inside async functions — these run like any other asynchronous JavaScript. An exception is that independent `$derived` expressions will update independently, even though they will run sequentially when they are first created:
This does not apply to sequential `await` expressions inside your `<script>` or inside async functions — these run like any other asynchronous JavaScript.
`$derived` is a special case: each derived updates independently when its dependencies change, but JavaScript still evaluates declarations in order.
```js
async function one() { return 1; }
async function two() { return 2; }
async function one(x) { return x; }
async function two(y) { return y; }
// ---cut---
// these will run sequentially the first time,
// but will update independently
let a = $derived(await one());
let b = $derived(await two());
let x = $state(1);
let y = $state(2);
let a = $derived(await one(x));
let b = $derived(await two(y));
```
Here, `b` will not be created until the `await one(x)` has resolved. Once created, `a` and `b` update independently — changes to `x` will only re-run `one(x)`, and changes to `y` will only re-run `two(y)`.
> [!NOTE] If you write code like this, expect Svelte to give you an [`await_waterfall`](runtime-warnings#Client-warnings-await_waterfall) warning