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

pull/11853/head
Dominic Gannaway 1 month 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);
}
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
// 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) {
var parent_node = /** @type {Element} */ (controlled_anchor.parentNode);
if (is_controlled) {
var parent_node = /** @type {Element} */ (
/** @type {Element} */ (controlled_anchor).parentNode
);
clear_text_content(parent_node);
parent_node.append(controlled_anchor);
parent_node.append(/** @type {Element} */ (controlled_anchor));
}
run_out_transitions(transitions, () => {
for (var i = 0; i < length; i++) {
destroy_effect(items[i].e);
destroy_effect(items[i].e, !is_controlled);
}
if (callback !== undefined) callback();

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

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

Loading…
Cancel
Save