diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index faaf157c10..0ebbf442f7 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -17,10 +17,8 @@ import { branch, effect, pause_effect, - get_out_transitions, - resume_effect, pause_effects, - destroy_effects + resume_effect } from '../../reactivity/effects.js'; import { source, mutable_source, set } from '../../reactivity/sources.js'; import { is_array, is_frozen, map_get, map_set } from '../../utils.js'; @@ -246,17 +244,9 @@ function reconcile_indexed_array(array, state, anchor, render_fn, flags) { effects.push(a_items[i].e); } - var transitions = get_out_transitions(effects); - var items = state.items; - - if (transitions.length === 0) { - destroy_effects(effects); - items.length = b; - } else { - pause_effects(effects, transitions, () => { - items.length = b; - }); - } + pause_effects(effects, () => { + state.items.length = b; + }); } } @@ -431,16 +421,11 @@ function reconcile_tracked_array(array, state, anchor, render_fn, flags, keys) { }); } - var transitions = get_out_transitions(to_destroy); - - if (transitions.length === 0) { - destroy_effects(to_destroy); + // TODO: would be good to avoid this closure in the case where we have no + // transitions at all. It would make it far more JIT friendly in the hot cases. + pause_effects(to_destroy, () => { state.items = b_items; - } else { - pause_effects(to_destroy, transitions, () => { - state.items = b_items; - }); - } + }); } /** diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index f17cc14345..4d54e4e887 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -313,38 +313,23 @@ export function pause_effect(effect, callback = noop) { * Pause multiple effects simultaneously, and coordinate their * subsequent destruction. Used in each blocks * @param {import('#client').Effect[]} effects - * @returns {import('#client').TransitionManager[]} + * @param {() => void} callback */ -export function get_out_transitions(effects) { +export function pause_effects(effects, callback = noop) { /** @type {import('#client').TransitionManager[]} */ var transitions = []; + var length = effects.length; - for (var i = 0; i < effects.length; i++) { + for (var i = 0; i < length; i++) { pause_children(effects[i], transitions, true); } - return transitions; -} - -/** - * @param {import('#client').Effect[]} effects - */ -export function destroy_effects(effects) { - for (var i = 0; i < effects.length; i++) { - destroy_effect(effects[i]); - } -} - -/** - * Pause multiple effects simultaneously, and coordinate their - * subsequent destruction. Used in each blocks - * @param {import('#client').Effect[]} effects - * @param {import('#client').TransitionManager[]} transitions - * @param {() => void} callback - */ -export function pause_effects(effects, transitions, callback = noop) { + // TODO: would be good to avoid this closure in the case where we have no + // transitions at all. It would make it far more JIT friendly in the hot cases. out(transitions, () => { - destroy_effects(effects); + for (var i = 0; i < length; i++) { + destroy_effect(effects[i]); + } callback(); }); } @@ -385,12 +370,13 @@ function pause_children(effect, transitions, local) { var child = effect.first; while (child !== null) { + var sibling = child.next; var transparent = (child.f & IS_ELSEIF) !== 0 || (child.f & BRANCH_EFFECT) !== 0; // TODO we don't need to call pause_children recursively with a linked list in place // it's slightly more involved though as we have to account for `transparent` changing // through the tree. pause_children(child, transitions, transparent ? local : false); - child = child.next; + child = sibling; } }