diff --git a/.changeset/current-sources-set.md b/.changeset/current-sources-set.md new file mode 100644 index 0000000000..e1a4dc43b2 --- /dev/null +++ b/.changeset/current-sources-set.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +perf: store `current_sources` as a `Set` for O(1) membership checks diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index f374f6a26b..218941ab67 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -32,7 +32,6 @@ import { } from '#client/constants'; import * as e from '../errors.js'; import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js'; -import { includes } from '../../shared/utils.js'; import { tag_proxy } from '../dev/tracing.js'; import { get_error } from '../../shared/dev.js'; import { component_context, is_runes } from '../context.js'; @@ -158,7 +157,7 @@ export function set(source, value, should_proxy = false) { (!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) && is_runes() && (active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 && - (current_sources === null || !includes.call(current_sources, source)) + (current_sources === null || !current_sources.has(source)) ) { e.state_unsafe_mutation(); } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 87abbd71b6..8d70eee43c 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -90,18 +90,14 @@ export function set_active_effect(effect) { /** * When sources are created within a reaction, reading and writing * them within that reaction should not cause a re-run - * @type {null | Source[]} + * @type {null | Set} */ export let current_sources = null; /** @param {Value} value */ export function push_reaction_value(value) { if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & DERIVED) !== 0)) { - if (current_sources === null) { - current_sources = [value]; - } else { - current_sources.push(value); - } + (current_sources ??= new Set()).add(value); } } @@ -202,7 +198,7 @@ function schedule_possible_effect_self_invalidation(signal, effect, root = true) var reactions = signal.reactions; if (reactions === null) return; - if (!async_mode_flag && current_sources !== null && includes.call(current_sources, signal)) { + if (!async_mode_flag && current_sources !== null && current_sources.has(signal)) { return; } @@ -540,7 +536,7 @@ export function get(signal) { // we don't add the dependency, because that would create a memory leak var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0; - if (!destroyed && (current_sources === null || !includes.call(current_sources, signal))) { + if (!destroyed && (current_sources === null || !current_sources.has(signal))) { var deps = active_reaction.deps; if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {