Skip to content

Commit d2978b5

Browse files
authored
createBatch reference doc rewrite (#982)
1 parent cba901d commit d2978b5

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

src/routes/reference/basic-reactivity/create-effect.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ createEffect((prevSum) => {
4343
```
4444

4545
Effects are meant primarily for side effects that read but don't write to the reactive system: it's best to avoid setting signals in effects, which without care can cause additional rendering or even infinite effect loops. Instead, prefer using [createMemo](/reference/basic-reactivity/create-memo) to compute new values that depend on other reactive values, so the reactive system knows what depends on what, and can optimize accordingly.
46+
If you do end up setting a signal within an effect, computations subscribed to that signal will be executed only once the effect completes; see [`batch`](/reference/reactive-utilities/batch) for more detail.
4647

4748
The first execution of the effect function is not immediate; it's scheduled to run after the current rendering phase (e.g., after calling the function passed to [render](/reference/rendering/render), [createRoot](/reference/reactive-utilities/create-root), or [runWithOwner](/reference/reactive-utilities/run-with-owner)).
4849
If you want to wait for the first execution to occur, use [queueMicrotask](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask) (which runs before the browser renders the DOM) or `await Promise.resolve()` or `setTimeout(..., 0)` (which runs after browser rendering).

src/routes/reference/reactive-utilities/batch.mdx

+86-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,89 @@ import { batch } from "solid-js"
88
function batch<T>(fn: () => T): T
99
```
1010

11-
This is a low level API that is used by Solid to batch updates.
12-
It holds executing downstream computations within the block until the end to prevent unnecessary recalculation.
13-
Solid Store's set method, Mutable Store's array methods, and Effects automatically wrap their code in a batch.
14-
This is useful for when you want to batch a set of computations that are not wrapped in a batch already.
11+
`batch` is a low-level API that batches updates together.
12+
More precisely, `batch(fn)` holds the execution of downstream computations
13+
during the `fn` block, executing them all together once the block `fn` returns.
14+
Thus, instead of a downstream computation executing after every dependency
15+
update, it will update just once at the end of the batch.
16+
17+
Batching improves performance by avoiding unnecessary recalculation.
18+
Suppose you have a downstream memo `down` that depends on
19+
multiple upstream signals `up1`, `up2`, and `up3`:
20+
21+
```ts
22+
import { createSignal, createMemo, createEffect } from "solid-js"
23+
const [up1, setUp1] = createSignal(1)
24+
const [up2, setUp2] = createSignal(2)
25+
const [up3, setUp3] = createSignal(3)
26+
const down = createMemo(() => up1() + up2() + up3())
27+
// For illustration, monitor when `down` gets recomputed:
28+
createEffect(() => console.log(down())) // outputs 6
29+
```
30+
31+
If you directly update all of the upstream signals outside of batch mode,
32+
then `down` will recompute every time.
33+
34+
```ts
35+
setUp1(4) // recomputes down, outputs 9
36+
setUp2(5) // recomputes down, outputs 12
37+
setUp3(6) // recomputes down, outputs 15
38+
```
39+
40+
If instead you update the upstream signals within a `batch`, then `down`
41+
will update only once at the end:
42+
43+
```ts
44+
batch(() => {
45+
setUp1(10) // doesn't update down yet
46+
setUp2(10) // doesn't update down yet
47+
setUp3(10) // doesn't update down yet
48+
}) // recomputes down, outputs 30
49+
```
50+
51+
The impact is even more dramatic if you have *m* downstream computations
52+
(memos, effects, etc.) that each depend on *n* upstream signals.
53+
Without batching, modifying all *n* upstream signals
54+
would cause *m n* updates to the downstream computations.
55+
With batching, modifying all *n* upstream signals
56+
would cause *m* updates to the downstream computations.
57+
Given that each update takes at least *n* time
58+
(just to read the upstream signals), this cost savings can be significant.
59+
Batching is also especially helpful when the downstream effects include
60+
DOM updates, which can be expensive.
61+
62+
Solid uses `batch` internally to automatically batch updates for you
63+
in a few cases:
64+
65+
* Within [`createEffect`](/reference/basic-reactivity/create-effect)
66+
and [`onMount`](/reference/lifecycle/on-mount)
67+
(unless they are outside a [root](/reference/reactive-utilities/create-root))
68+
* Within the [setter of a store](/reference/store-utilities/create-store#setter)
69+
(which can update several properties at once)
70+
* Within array methods (e.g. `Array.prototype.splice`) of a
71+
[mutable store](/reference/store-utilities/create-mutable)
72+
(which can update several elements at once)
73+
74+
These save you from having to use `batch` yourself in many cases.
75+
For the most part, automatic batching should be transparent to you,
76+
because accessing a signal or memo will cause it to update if it is out of date
77+
(as of Solid 1.4). For example:
78+
79+
```ts
80+
batch(() => {
81+
setUp1(11) // doesn't update down yet
82+
setUp2(11) // doesn't update down yet
83+
setUp3(11) // doesn't update down yet
84+
console.log(down()) // recomputes down, outputs 33
85+
setUp1(12) // doesn't update down yet
86+
setUp2(12) // doesn't update down yet
87+
setUp3(12) // doesn't update down yet
88+
}) // recomputes down, outputs 36
89+
```
90+
91+
You can think of `batch(fn)` as setting a global "batch mode" variable,
92+
calling the function `fn`, and then restoring the global variable to its
93+
previous value.
94+
This means that you can nest `batch` calls, and they will form one big batch.
95+
It also means that, if `fn` is asynchronous,
96+
only the updates before the first `await` will be batched.

0 commit comments

Comments
 (0)