Skip to content

Commit 3c84c21

Browse files
authored
fix: improve controlled each block cleanup performance (#11839)
1 parent aa91ed2 commit 3c84c21

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

.changeset/gentle-ties-fetch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: improve controlled each block cleanup performance

packages/svelte/src/internal/client/dom/blocks/each.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,20 @@ function pause_effects(items, controlled_anchor, callback) {
6868
pause_children(items[i].e, transitions, true);
6969
}
7070

71+
var is_controlled = length > 0 && transitions.length === 0 && controlled_anchor !== null;
7172
// If we have a controlled anchor, it means that the each block is inside a single
7273
// DOM element, so we can apply a fast-path for clearing the contents of the element.
73-
if (length > 0 && transitions.length === 0 && controlled_anchor !== null) {
74-
var parent_node = /** @type {Element} */ (controlled_anchor.parentNode);
74+
if (is_controlled) {
75+
var parent_node = /** @type {Element} */ (
76+
/** @type {Element} */ (controlled_anchor).parentNode
77+
);
7578
clear_text_content(parent_node);
76-
parent_node.append(controlled_anchor);
79+
parent_node.append(/** @type {Element} */ (controlled_anchor));
7780
}
7881

7982
run_out_transitions(transitions, () => {
8083
for (var i = 0; i < length; i++) {
81-
destroy_effect(items[i].e);
84+
destroy_effect(items[i].e, !is_controlled);
8285
}
8386

8487
if (callback !== undefined) callback();

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,16 +311,17 @@ export function execute_effect_teardown(effect) {
311311

312312
/**
313313
* @param {import('#client').Effect} effect
314+
* @param {boolean} [remove_dom]
314315
* @returns {void}
315316
*/
316-
export function destroy_effect(effect) {
317+
export function destroy_effect(effect, remove_dom = true) {
317318
var dom = effect.dom;
318319

319-
if (dom !== null) {
320+
if (dom !== null && remove_dom) {
320321
remove(dom);
321322
}
322323

323-
destroy_effect_children(effect);
324+
destroy_effect_children(effect, remove_dom);
324325
remove_reactions(effect, 0);
325326
set_signal_status(effect, DESTROYED);
326327

packages/svelte/src/internal/client/runtime.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,16 +478,17 @@ export function remove_reactions(signal, start_index) {
478478

479479
/**
480480
* @param {import('#client').Reaction} signal
481+
* @param {boolean} [remove_dom]
481482
* @returns {void}
482483
*/
483-
export function destroy_effect_children(signal) {
484+
export function destroy_effect_children(signal, remove_dom = true) {
484485
let effect = signal.first;
485486
signal.first = null;
486487
signal.last = null;
487488
var sibling;
488489
while (effect !== null) {
489490
sibling = effect.next;
490-
destroy_effect(effect);
491+
destroy_effect(effect, remove_dom);
491492
effect = sibling;
492493
}
493494
}

0 commit comments

Comments
 (0)