From ab1c07e9f563a37d64a6406e75d24c1422805f05 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 17 Sep 2024 22:30:13 -0400 Subject: [PATCH] mark effect root as queued instead of adding a branch effect --- .../svelte/src/internal/client/constants.js | 1 + .../src/internal/client/reactivity/effects.js | 12 +---- packages/svelte/src/internal/client/render.js | 48 ++++++++++--------- .../svelte/src/internal/client/runtime.js | 12 ++++- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/packages/svelte/src/internal/client/constants.js b/packages/svelte/src/internal/client/constants.js index 19a412726d..35ee8292ef 100644 --- a/packages/svelte/src/internal/client/constants.js +++ b/packages/svelte/src/internal/client/constants.js @@ -18,6 +18,7 @@ export const EFFECT_TRANSPARENT = 1 << 15; export const LEGACY_DERIVED_PROP = 1 << 16; export const INSPECT_EFFECT = 1 << 17; export const HEAD_EFFECT = 1 << 18; +export const EFFECT_QUEUED = 1 << 19; export const STATE_SYMBOL = Symbol('$state'); export const STATE_SYMBOL_METADATA = Symbol('$state metadata'); diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 001f39da5a..c4f9bdf95e 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -237,17 +237,7 @@ export function inspect_effect(fn) { * @returns {() => void} */ export function effect_root(fn) { - const effect = create_effect( - ROOT_EFFECT, - () => { - branch(() => { - // We return a noop if no function is returned to ensure that the branch - // is attached to the effect tree otherwise it will count as inert - return fn() || noop; - }); - }, - true - ); + const effect = create_effect(ROOT_EFFECT, fn, true); return () => { destroy_effect(effect); diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 68817cac70..5f0e56e49b 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -10,7 +10,7 @@ import { } from './dom/operations.js'; import { HYDRATION_END, HYDRATION_ERROR, HYDRATION_START } from '../../constants.js'; import { push, pop, component_context, active_effect } from './runtime.js'; -import { effect_root } from './reactivity/effects.js'; +import { branch, effect_root } from './reactivity/effects.js'; import { hydrate_next, hydrate_node, @@ -225,33 +225,35 @@ function _mount(Component, { target, anchor, props = {}, events, context, intro var component = undefined; var unmount = effect_root(() => { - if (context) { - push({}); - var ctx = /** @type {ComponentContext} */ (component_context); - ctx.c = context; - } + branch(() => { + if (context) { + push({}); + var ctx = /** @type {ComponentContext} */ (component_context); + ctx.c = context; + } - if (events) { - // We can't spread the object or else we'd lose the state proxy stuff, if it is one - /** @type {any} */ (props).$$events = events; - } + if (events) { + // We can't spread the object or else we'd lose the state proxy stuff, if it is one + /** @type {any} */ (props).$$events = events; + } - if (hydrating) { - assign_nodes(/** @type {TemplateNode} */ (anchor), null); - } + if (hydrating) { + assign_nodes(/** @type {TemplateNode} */ (anchor), null); + } - should_intro = intro; - // @ts-expect-error the public typings are not what the actual function looks like - component = Component(anchor, props) || {}; - should_intro = true; + should_intro = intro; + // @ts-expect-error the public typings are not what the actual function looks like + component = Component(anchor, props) || {}; + should_intro = true; - if (hydrating) { - /** @type {Effect} */ (active_effect).nodes_end = hydrate_node; - } + if (hydrating) { + /** @type {Effect} */ (active_effect).nodes_end = hydrate_node; + } - if (context) { - pop(); - } + if (context) { + pop(); + } + }); return () => { for (var event_name of registered_events) { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index fbd3df8e5e..d5aa7b5e48 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -22,7 +22,8 @@ import { BLOCK_EFFECT, ROOT_EFFECT, LEGACY_DERIVED_PROP, - DISCONNECTED + DISCONNECTED, + EFFECT_QUEUED } from './constants.js'; import { flush_tasks } from './dom/task.js'; import { add_owner } from './dev/ownership.js'; @@ -504,6 +505,10 @@ function flush_queued_root_effects(root_effects) { for (var i = 0; i < length; i++) { var effect = root_effects[i]; + if ((effect.f & EFFECT_QUEUED) !== 0) { + effect.f ^= EFFECT_QUEUED; + } + // When working with custom elements, the root effects might not have a root if (effect.first === null && (effect.f & BRANCH_EFFECT) === 0) { flush_queued_effects([effect]); @@ -590,6 +595,11 @@ export function schedule_effect(signal) { if ((flags & CLEAN) === 0) return; effect.f ^= CLEAN; } + + if ((flags & ROOT_EFFECT) !== 0) { + if ((flags & EFFECT_QUEUED) !== 0) return; + effect.f ^= EFFECT_QUEUED; + } } queued_root_effects.push(effect);