Skip to content

Introduce Mechanism to Mark Specific $state Properties as Non-Reactive #15689

Open
@kugry-repo

Description

@kugry-repo

Describe the problem

Abstract:

In Svelte 5, the $state rune creates deeply reactive state proxies, ensuring that any changes to nested properties trigger UI updates. However, there are scenarios where developers need certain properties within a $state object to remain non-reactive to optimize performance and prevent unintended reactivity. This proposal suggests introducing a mechanism to mark specific properties within a $state object as non-reactive.​

Motivation:

Developers often work with complex data structures where not all properties require reactivity. For instance, when integrating with third-party libraries or managing large datasets, making every property reactive can lead to performance overhead and unintended side effects. Providing a way to designate certain properties as non-reactive would offer more control over the reactivity system and enhance performance in such scenarios.​

Alternatives Considered:

Currently, developers can manage non-reactive data by storing it outside of the $state object or using workarounds like JSON serialization. However, these approaches can lead to less readable and maintainable code. Introducing a built-in method to handle non-reactive properties would provide a more elegant and intuitive solution.​

Conclusion:

Implementing a feature to mark specific properties within a $state object as non-reactive would offer developers greater control over Svelte's reactivity system, leading to improved performance and more predictable behavior in complex applications.

Describe the proposed solution

Proposed Solution:

1. Explicit Opt-Out using $state.raw():

Introduce a method to mark specific properties within a $state object as non-reactive. This could be achieved by implementing a $state.raw method that allows developers to wrap properties they wish to exclude from reactivity. For example:​

import { $state } from 'svelte';

let editorContent = { /* large non-reactive data */ };

let state = $state({
  reactiveProperty: 'This is reactive',
  nonReactiveProperty: $state.raw(editorContent)
});

In this example, reactiveProperty would be reactive, while nonReactiveProperty would remain non-reactive, preventing unnecessary performance overhead.​

2. Automatic Opt-Out via Naming Convention

Any property name that starts with an underscore (e.g. _editorContent) is automatically excluded from reactivity. For example:

const state = $state({
  title: 'My Document',
  _editorContent: editorModel // will not be proxied
});

This makes non-reactive state easier to declare and visually distinct, encouraging cleaner separation between reactive UI data and unmanaged content.

Considerations for Underscore Prefixing:

  • Easy to learn and apply.
  • Avoids introducing new API surface.
  • Matches existing informal conventions for private or internal properties.
  • Could be opt-in behavior behind a flag, if needed for backward compatibility.

Importance

would make my life easier

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