fix: improve controlled each block cleanup performance (#11839)

pull/11853/head
Dominic Gannaway 1 year ago committed by GitHub
parent aa91ed2c1c
commit 3c84c21a03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: improve controlled each block cleanup performance

@ -68,17 +68,20 @@ function pause_effects(items, controlled_anchor, callback) {
pause_children(items[i].e, transitions, true); pause_children(items[i].e, transitions, true);
} }
var is_controlled = length > 0 && transitions.length === 0 && controlled_anchor !== null;
// If we have a controlled anchor, it means that the each block is inside a single // If we have a controlled anchor, it means that the each block is inside a single
// DOM element, so we can apply a fast-path for clearing the contents of the element. // DOM element, so we can apply a fast-path for clearing the contents of the element.
if (length > 0 && transitions.length === 0 && controlled_anchor !== null) { if (is_controlled) {
var parent_node = /** @type {Element} */ (controlled_anchor.parentNode); var parent_node = /** @type {Element} */ (
/** @type {Element} */ (controlled_anchor).parentNode
);
clear_text_content(parent_node); clear_text_content(parent_node);
parent_node.append(controlled_anchor); parent_node.append(/** @type {Element} */ (controlled_anchor));
} }
run_out_transitions(transitions, () => { run_out_transitions(transitions, () => {
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
destroy_effect(items[i].e); destroy_effect(items[i].e, !is_controlled);
} }
if (callback !== undefined) callback(); if (callback !== undefined) callback();

@ -311,16 +311,17 @@ export function execute_effect_teardown(effect) {
/** /**
* @param {import('#client').Effect} effect * @param {import('#client').Effect} effect
* @param {boolean} [remove_dom]
* @returns {void} * @returns {void}
*/ */
export function destroy_effect(effect) { export function destroy_effect(effect, remove_dom = true) {
var dom = effect.dom; var dom = effect.dom;
if (dom !== null) { if (dom !== null && remove_dom) {
remove(dom); remove(dom);
} }
destroy_effect_children(effect); destroy_effect_children(effect, remove_dom);
remove_reactions(effect, 0); remove_reactions(effect, 0);
set_signal_status(effect, DESTROYED); set_signal_status(effect, DESTROYED);

@ -478,16 +478,17 @@ export function remove_reactions(signal, start_index) {
/** /**
* @param {import('#client').Reaction} signal * @param {import('#client').Reaction} signal
* @param {boolean} [remove_dom]
* @returns {void} * @returns {void}
*/ */
export function destroy_effect_children(signal) { export function destroy_effect_children(signal, remove_dom = true) {
let effect = signal.first; let effect = signal.first;
signal.first = null; signal.first = null;
signal.last = null; signal.last = null;
var sibling; var sibling;
while (effect !== null) { while (effect !== null) {
sibling = effect.next; sibling = effect.next;
destroy_effect(effect); destroy_effect(effect, remove_dom);
effect = sibling; effect = sibling;
} }
} }

Loading…
Cancel
Save