Skip to content

Performance of accessing deeply reactive state #11851

Closed
@peterkogo

Description

@peterkogo

Describe the bug

Context

Our libraries state is an array of objects. The deepest nesting level is maybe another object in each object.
Having array sizes of thousands of elements is not unheard of and has been completely manageable performance-wise in Svelte 4.

Issue:

Because this array is representing state I converted what was previously a store into a deeply reactive state.
I am observing quite a heavy performance impact. The surprising part is that this is not only limited to the rendering of components based on that state, but also affects simple access of the array in a non-stateful context.

For reference, iterating over an array with 1000 objects of type { position: { x: number, y: number } } yields quite different results - deeply reactive state however, is very far off.

Here are the results of a simple benchmark comparing $state(array) to $state.frozen(array) and to simply accessing the array itself. The function used for taking the measurements is a simple summation (see REPL below for full code).

let sum = 0;
for (const elem of array) {
  sum += elem.position.x + elem.position.y;
}
+--------------+---------+--------------------+--------+---------+
| Task Name    | ops/sec | Average Time (ns)  | Margin | Samples |
+--------------+---------+--------------------+--------+---------+
| baseline     | 465,124 | 2149.9602650215506 | ±6.13% | 46559   |
| frozen state | 161,428 | 6194.690263273545  | ±6.10% | 16159   |
| deep state   | 5,890   | 169779.2869269949  | ±3.03% | 589     |
+--------------+---------+--------------------+--------+---------+

Is this expected, or am I doing something wrong here? I test my code with production builds and can observe similar behavior, but am I accidentally benchmarking dev mode in the REPL?

Can I bail out of the runtime reactivity code path when I simply want to access state programmatically in an unstateful manner?

Reproduction

REPL with benchmark. Check performance tab when hitting change stuff to observe rendering performance.

Logs

No response

System Info

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions